PluginProbe
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits / 3.2.2
Master Addons for Elementor – Elementor Addons, Widgets, Mega Menu Builder, Popup Builder, Widget Builder & Template Kits v3.2.2
3.2.2 3.2.3 3.2.1 3.2.0 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.9 trunk 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.3 1.1.4 1.1.5 All 174 releases
← All changes | lib/Recommended.php +52 -12 3.1.23.2.2 View file →
@@ -59,8 +59,36 @@
59 59 }
60 60 }
61 61
62 62 /**
63 + * Exact allowlist of installed plugin files that belong to our known slugs.
64 + *
65 + * Returns real plugin basenames (e.g. "elementor/elementor.php") taken from the
66 + * actual installed plugin set, filtered to the slugs we manage. Used to validate
67 + * any $_POST plugin-file value before it reaches activate_plugin()/upgrade(), so
68 + * arbitrary input can never select an unrelated plugin file.
69 + *
70 + * @return string[]
71 + */
72 + protected function get_allowed_plugin_files()
73 + {
74 + if (!function_exists('get_plugins')) {
75 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
76 + }
77 +
78 + $known_slugs = array_values(wp_list_pluck($this->plugins_list, 'slug'));
79 + $allowed = array();
80 +
81 + foreach (array_keys(get_plugins()) as $plugin_file) {
82 + if (in_array(dirname($plugin_file), $known_slugs, true)) {
83 + $allowed[] = $plugin_file;
84 + }
85 + }
86 +
87 + return $allowed;
88 + }
89 +
90 + /**
63 91 * Menu Items
64 92 *
65 93 * @author Jewel Theme <support@jeweltheme.com>
66 94 */
@@ -288,13 +316,15 @@
288 316 if ((is_multisite() && !is_network_admin()) || !current_user_can('install_plugins')) {
289 317 wp_send_json_error(array('mess' => __('Invalid access', 'master-addons')));
290 318 }
291 319
292 - $file = sanitize_text_field(wp_unslash($_POST['file']));
293 - $known_slugs = array_values(wp_list_pluck($this->plugins_list, 'slug'));
294 - $file_slug = dirname($file);
320 + $file = sanitize_text_field(wp_unslash($_POST['file']));
295 321
296 - if (!in_array($file_slug, $known_slugs)) {
322 + // Enforce an exact allowlist of real installed plugin files that
323 + // belong to our known slugs. Arbitrary input (or a crafted basename
324 + // whose dirname happens to match a slug) must never reach
325 + // activate_plugin(); only an exact installed plugin file passes.
326 + if (!in_array($file, $this->get_allowed_plugin_files(), true)) {
297 327 wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons')));
298 328 }
299 329
300 330 $result = activate_plugin($file);
@@ -350,19 +380,29 @@
350 380 if ((is_multisite() && !is_network_admin()) || !current_user_can('install_plugins')) {
351 381 wp_send_json_error(array('mess' => __('Invalid access', 'master-addons')));
352 382 }
353 383
354 - $plugin = sanitize_text_field(wp_unslash($_POST['plugin']));
355 - $plugin_links = array_values(wp_list_pluck($this->plugins_list, 'download_link'));
356 - $known_slugs = array_values(wp_list_pluck($this->plugins_list, 'slug'));
357 - $plugin_slug = dirname($plugin);
358 - $is_valid = in_array($plugin, $plugin_links) || ($plugin_slug !== '.' && in_array($plugin_slug, $known_slugs));
384 + $plugin = sanitize_text_field(wp_unslash($_POST['plugin']));
385 + $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'install';
359 386
360 - if (!$is_valid) {
361 - wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons')));
387 + // Validate against an exact allowlist that depends on the operation:
388 + // - install: $plugin is a package source; must be exactly one of our
389 + // known download links.
390 + // - upgrade: $plugin is a plugin file; must be exactly one of the real
391 + // installed plugin files under our known slugs.
392 + // dirname()-based matching is intentionally NOT used — it would accept a
393 + // crafted value whose directory merely resembles a known slug.
394 + if ('install' === $type) {
395 + $plugin_links = array_values(wp_list_pluck($this->plugins_list, 'download_link'));
396 + if (!in_array($plugin, $plugin_links, true)) {
397 + wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons')));
398 + }
399 + } else {
400 + if (!in_array($plugin, $this->get_allowed_plugin_files(), true)) {
401 + wp_send_json_error(array('mess' => __('Invalid plugin', 'master-addons')));
402 + }
362 403 }
363 404
364 - $type = isset($_POST['type']) ? sanitize_text_field(wp_unslash($_POST['type'])) : 'install';
365 405 $skin = new \WP_Ajax_Upgrader_Skin();
366 406 $upgrader = new \Plugin_Upgrader($skin);
367 407
368 408 if ('install' === $type) {