CVE-2025-12975

CTX Feed – WooCommerce Product Feed Manager <= 6.6.11 - Missing Authorization to Authenticated (Shop Manager+) Arbitrary Plugin Installation

highMissing Authorization
7.2
CVSS Score
7.2
CVSS Score
high
Severity
6.6.12
Patched in
1d
Time to patch

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:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=6.6.11
PublishedFebruary 18, 2026
Last updatedFebruary 19, 2026

What Changed in the Fix

Changes introduced in v6.6.12

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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_woocommerce or edit_posts) or higher.
  • Preconditions:
    1. The attacker must be logged in as a Shop Manager.
    2. The attacker must obtain a valid AJAX nonce for the woo_feed_plugin_installing action.

3. Code Flow

  1. Entry Point: The AJAX action woo_feed_plugin_installing is registered (likely in includes/action-handler.php via add_action( 'wp_ajax_woo_feed_plugin_installing', ... )).
  2. AJAX Call: The client-side script admin/js/woo-feed-our-plugins.js triggers a POST request to admin-ajax.php.
  3. Execution:
    • admin-ajax.php dispatches the request to woo_feed_plugin_installing().
    • The function verifies the nonce using check_ajax_referer() or wp_verify_nonce() using the key _ajax_nonce.
    • Vulnerability: The function proceeds to install the plugin specified in the data parameter without calling current_user_can( 'install_plugins' ).
  4. 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.

  1. Identify Script Loading: The script admin/js/woo-feed-our-plugins.js is loaded on CTX Feed admin pages, specifically the "Our Plugins" or "Recommended Plugins" section.
  2. Page Navigation: Navigate to the CTX Feed settings page.
    • URL: /wp-admin/admin.php?page=webappick-wp-feed-settings (or check for a submenu like webappick-wp-feed-about).
  3. Extraction:
    • Use browser_eval to 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.

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

  1. Target Version: Install CTX Feed version 6.6.11.
  2. User Creation:
    wp user create attacker attacker@example.com --role=shop_manager --user_pass=password
    
  3. 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 in admin/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.

Research Findings
Static analysis — not yet PoC-verified

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

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.11/admin/js/woo-feed-our-plugins.js /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.12/admin/js/woo-feed-our-plugins.js
--- /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.11/admin/js/woo-feed-our-plugins.js	2025-02-17 04:33:44.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.12/admin/js/woo-feed-our-plugins.js	2025-12-11 10:21:26.000000000 +0000
@@ -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) }
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.11/includes/helper.php /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.12/includes/helper.php
--- /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.11/includes/helper.php	2025-11-28 06:14:28.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/webappick-product-feed-for-woocommerce/6.6.12/includes/helper.php	2025-12-11 10:21:26.000000000 +0000
@@ -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.