Commit 887863a283 for wordpress.org
commit 887863a28304e5e395e128bf6a72a94164f73854
Author: adamsilverstein <adamsilverstein@git.wordpress.org>
Date: Thu Sep 17 17:25:46 2026 +0000
Plugins: Require network plugin authority to Ajax-activate a network-only plugin.
Props whyisjake, johnbillion, jeremyfelt, dmsnell, buffer1024.
Built from https://develop.svn.wordpress.org/trunk@63657
git-svn-id: http://core.svn.wordpress.org/trunk@62831 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php
index 747bcc75e5..126b6b75d4 100644
--- a/wp-admin/includes/ajax-actions.php
+++ b/wp-admin/includes/ajax-actions.php
@@ -4615,6 +4615,12 @@ function wp_ajax_activate_plugin() {
wp_send_json_error( $status );
}
+ // A network-only plugin is activated for the entire network.
+ if ( is_multisite() && is_network_only_plugin( $status['plugin'] ) && ! current_user_can( 'manage_network_plugins' ) ) {
+ $status['errorMessage'] = __( 'Sorry, you are not allowed to activate this plugin.' );
+ wp_send_json_error( $status );
+ }
+
if ( is_plugin_active( $status['plugin'] ) ) {
$status['errorMessage'] = sprintf(
/* translators: %s: Plugin name. */
diff --git a/wp-admin/includes/plugin.php b/wp-admin/includes/plugin.php
index 9969316ab8..53d933d07e 100644
--- a/wp-admin/includes/plugin.php
+++ b/wp-admin/includes/plugin.php
@@ -598,11 +598,17 @@ function is_plugin_active_for_network( $plugin ) {
* Checks for "Site Wide Only: true" for backward compatibility.
*
* @since 3.0.0
+ * @since 7.1.1 The `$plugin` path is normalized with `plugin_basename()` and `trim()`,
+ * matching how `activate_plugin()` resolves it.
*
- * @param string $plugin Path to the plugin file relative to the plugins directory.
+ * @param string $plugin Path to the plugin file. Accepts a path relative to the plugins
+ * directory, or an absolute path, with or without surrounding whitespace.
* @return bool True if plugin is network only, false otherwise.
*/
function is_network_only_plugin( $plugin ) {
+ // Normalize the path the same way activate_plugin() does, so both agree on the file.
+ $plugin = plugin_basename( trim( $plugin ) );
+
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
if ( $plugin_data ) {
return $plugin_data['Network'];
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 118762a146..30242fafe1 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-alpha-63656';
+$wp_version = '7.2-alpha-63657';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.