Make WordPress Core

Opened 3 years ago

Last modified 3 years ago

#54259 new enhancement

The function deactivate_plugins should run only in the backend

Reported by: giuse's profile giuse Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Plugins Keywords:
Focuses: Cc:

Description

Hello.

I think the function deactivate_plugins (https://developer.wordpress.org/reference/functions/deactivate_plugins/) should run only in the backend, never on the frontend.
Many plugin authors abuse this function to deactivate their plugin when it depends on another plugin that is inactive. If they don't check if the page is visited on the backend this function may cause serious issues in some situations.
If the presence of the "parent" plugin is not checked properly, by allowing this function on the frontend, you may have some plugins that are not intentionally disabled.

Here is an example to clarify what I mean.

We have plugin B that depends on plugin A.

In the code of the main file of plugin B it's written something like this:

<?php
$plugin_B = plugin_basename( __FILE__ );
$plugin_A = 'plugin-A/plugin-A.php';

if( !in_array( $plugin_A,get_option( 'active_plugins' ) ){
   deactivate_plugins( $plugin_B )
}

The option 'active_plugins' can be filtered by a mu-plugin that runs before plugin B. This means that if on a specific page the filter of 'active_plugins' returns a set of plugins without plugin A, on frontend the code above will deactivate plugin B if that specific page is visited. And it will do it globally, not just filtering the option 'active_plugins', because the function deactivate_plugins will save the option 'active_plugins' with the wrong set of active plugins.

I think the option 'active_plugins' should never be saved after visiting the frontend, but this is what the function deactivate_plugins may do in a situation like that one described in the example above.

I would just add the line if( !is_admin() ) return;

function deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
   if( !is_admin() ) return;
   //....
}

Change History (2)

#1 @audrasjb
3 years ago

  • Component changed from General to Upgrade/Install
  • Version 5.8.1 deleted

#2 @SergeyBiryukov
3 years ago

  • Component changed from Upgrade/Install to Plugins
Note: See TracTickets for help on using tickets.