CVE-2025-15400

OpenPix <= 2.13.3 - Missing Authorization to Authenticated (Subscriber+) Settings Update

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The OpenPix for WooCommerce plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.13.3. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.13.3
PublishedFebruary 11, 2026
Last updatedFebruary 16, 2026
Research Plan
Unverified

Since source files for version 2.13.3 are not provided, this plan is based on the vulnerability description, the patch diff patterns common in similar WooCommerce payment gateway vulnerabilities, and the specific behavior of the OpenPix plugin architecture. ### 1. Vulnerability Summary The **OpenPi…

Show full research plan

Since source files for version 2.13.3 are not provided, this plan is based on the vulnerability description, the patch diff patterns common in similar WooCommerce payment gateway vulnerabilities, and the specific behavior of the OpenPix plugin architecture.

1. Vulnerability Summary

The OpenPix for WooCommerce plugin (<= 2.13.3) fails to implement a capability check (Missing Authorization) in an AJAX handler responsible for updating plugin settings. While the handler may or may not implement a nonce check, it lacks a call to current_user_can('manage_options') or current_user_can('manage_woocommerce'). This allows any authenticated user, including those with Subscriber roles, to modify critical plugin configurations, such as the API AppID, webhook secrets, or payment status mappings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: openpix_save_settings (inferred) or openpix_update_settings (inferred).
  • Method: POST
  • Parameters:
    • action: The AJAX action string.
    • security or _wpnonce: The nonce (if required).
    • settings: An array or set of individual parameters (e.g., app_id, webhook_secret) to be saved to the database.
  • Authentication: Subscriber-level (PR:L).
  • Impact: By changing the app_id, an attacker can redirect payments to their own OpenPix account.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler in its constructor or an initialization hook:
    add_action( 'wp_ajax_openpix_save_settings', [ $this, 'save_settings' ] );
  2. Vulnerable Function: The save_settings function is called.
  3. Missing Check: The function likely calls check_ajax_referer() (nonce check) but fails to call current_user_can().
  4. Sink: The function iterates through $_POST data and calls update_option( 'woocommerce_openpix_settings', ... ) or update_option( 'openpix_config', ... ).

4. Nonce Acquisition Strategy

If the endpoint requires a nonce, we must find where the plugin localizes it. OpenPix often enqueues scripts on the WooCommerce checkout page to handle PIX payment displays.

  1. Identify the Script Variable: Look for wp_localize_script calls in the plugin source (e.g., includes/class-openpix-for-woocommerce-frontend.php).
  2. JS Variable Name: Likely openpix_vars or openpix_obj (inferred).
  3. Procedure:
    • Create a simple product and a Subscriber user.
    • Log in as the Subscriber.
    • Navigate to the Shop page or a page containing the OpenPix checkout elements.
    • In the browser console, locate the nonce:
      // Example guess based on common naming conventions
      console.log(window.openpix_vars?.nonce); 
      

5. Exploitation Strategy

This plan assumes the AJAX action is openpix_save_settings and it requires a nonce.

  1. Step 1: Discover the exact AJAX action.
    Search the codebase for add_action( 'wp_ajax_.
  2. Step 2: Obtain the Nonce.
    Use browser_navigate to visit the site as a Subscriber and browser_eval to extract the nonce from the localized script.
  3. Step 3: Craft the Payload.
    Construct a POST request to admin-ajax.php.
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=openpix_save_settings&security=[NONCE]&app_id=attacker_app_id&webhook_secret=attacker_secret
    
  4. Step 4: Execute. Use the http_request tool to send the payload.

6. Test Data Setup

  1. Create Subscriber: wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  2. Install/Activate WooCommerce: Ensure WooCommerce is active as the plugin depends on it.
  3. Configure OpenPix: Set an initial "legit" AppID via wp option update woocommerce_openpix_settings '{"app_id":"original_id"}' (JSON structure inferred).

7. Expected Results

  • Response: The server should return a 200 OK or a JSON success message (e.g., {"success":true}).
  • State Change: The plugin's configuration option in the wp_options table should be updated with the attacker-supplied values.

8. Verification Steps

After sending the HTTP request, verify the database state using WP-CLI:

# Check if the settings were updated
wp option get woocommerce_openpix_settings --format=json

If the output contains "app_id":"attacker_app_id", the exploitation is confirmed.

9. Alternative Approaches

  • No Nonce: If check_ajax_referer is also missing, the exploit becomes unauthenticated/CSRF. Omit the nonce and try the request.
  • REST API: Check if the plugin registers any routes via register_rest_route. If so, look for a permission_callback that returns true or checks for is_user_logged_in() instead of a specific capability.
  • Parameter Guessing: If the settings are not saved as an array but as individual options, try parameters like openpix_appid or openpix_key. Search for update_option calls within the handler to find exact keys.

Note on Identifiers: Since source is not provided, the following identifiers are (inferred) and must be verified in the actual environment:

  • Action: openpix_save_settings
  • Option: woocommerce_openpix_settings
  • Nonce Key: security
  • JS Object: openpix_vars
Research Findings
Static analysis — not yet PoC-verified

Summary

The OpenPix for WooCommerce plugin (<= 2.13.3) fails to implement capability checks in its AJAX handler responsible for updating plugin settings. This allows authenticated users with low-level privileges, such as Subscribers, to modify critical plugin configurations including API AppIDs and webhook secrets, which could be used to redirect payments to an attacker-controlled account.

Vulnerable Code

// Inferred from vulnerability description and typical WooCommerce payment gateway architecture
// Likely located in a class handling AJAX requests or plugin initialization

add_action( 'wp_ajax_openpix_save_settings', 'openpix_save_settings_handler' );

function openpix_save_settings_handler() {
    // Nonce check might be present to prevent CSRF, but authorization is missing
    check_ajax_referer( 'openpix_nonce_action', 'security' );

    // VULNERABILITY: Missing current_user_can('manage_woocommerce') or similar check

    if ( isset( $_POST['settings'] ) ) {
        $settings = $_POST['settings'];
        update_option( 'woocommerce_openpix_settings', $settings );
        wp_send_json_success();
    }
}

Security Fix

--- a/includes/class-openpix-ajax.php
+++ b/includes/class-openpix-ajax.php
@@ -3,6,10 +3,10 @@
 function openpix_save_settings_handler() {
     check_ajax_referer( 'openpix_nonce_action', 'security' );
 
+    if ( ! current_user_can( 'manage_woocommerce' ) ) {
+        wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
+    }
+
     if ( isset( $_POST['settings'] ) ) {
         $settings = $_POST['settings'];
         update_option( 'woocommerce_openpix_settings', $settings );

Exploit Outline

1. Authenticate as a Subscriber-level user (or any role with access to the WordPress dashboard). 2. Obtain a valid security nonce by visiting a page where the plugin localizes its scripts (e.g., the checkout page or a front-end script targeting the OpenPix gateway). The nonce is likely stored in a JavaScript variable such as 'openpix_vars.nonce'. 3. Construct a POST request to '/wp-admin/admin-ajax.php'. 4. Include the following parameters in the payload: 'action' set to the vulnerable settings update hook (e.g., 'openpix_save_settings'), 'security' containing the retrieved nonce, and 'settings' containing malicious configuration values (e.g., a rogue AppID). 5. Send the request to overwrite the plugin's global configuration in the database, effectively hijacking the payment gateway's target account.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.