CVE-2026-24580

Ecwid Shopping Cart <= 7.0.5 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
7.0.6
Patched in
16d
Time to patch

Description

The Ecwid Shopping Cart plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 7.0.5. 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<=7.0.5
PublishedJanuary 19, 2026
Last updatedFebruary 3, 2026
Affected pluginecwid-shopping-cart

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on **CVE-2026-24580**, a Missing Authorization vulnerability in the **Ecwid Shopping Cart** plugin for WordPress. This vulnerability allows authenticated users (Subscriber-level and above) to perform actions that should be restricted to administrators. --- ### 1. Vulnera…

Show full research plan

This research plan focuses on CVE-2026-24580, a Missing Authorization vulnerability in the Ecwid Shopping Cart plugin for WordPress. This vulnerability allows authenticated users (Subscriber-level and above) to perform actions that should be restricted to administrators.


1. Vulnerability Summary

  • Vulnerability: Missing Authorization
  • Location: Likely within an AJAX handler registered via wp_ajax_.
  • Cause: The plugin registers AJAX actions for authenticated users but fails to implement a current_user_can('manage_options') check inside the callback function.
  • Impact: An attacker with a Subscriber account can modify sensitive plugin settings, such as the Ecwid Store ID, API tokens, or other configuration options, potentially redirecting store revenue or hijacking the connection between the WordPress site and the Ecwid platform.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action (Inferred): ecwid_ajax_set_option or ecwid_save_settings. (Research suggests Ecwid uses a central AJAX handler for settings updates).
  • Parameters:
    • action: The AJAX action string.
    • _ajax_nonce or nonce: The CSRF token.
    • option: The name of the option to update.
    • value: The new value for the option.
  • Authentication: Authenticated (Subscriber level).
  • Preconditions: The attacker must have a valid login.

3. Code Flow (Inferred)

  1. Registration: The plugin registers an AJAX action:
    add_action( 'wp_ajax_ecwid_set_option', array( $this, 'ajax_set_option' ) );
  2. Trigger: A Subscriber sends a POST request to admin-ajax.php with action=ecwid_set_option.
  3. Vulnerable Function: The ajax_set_option function (likely in includes/class-ecwid-admin.php or lib/ecwid_ajax_functions.php) executes.
  4. The Flaw:
    public function ajax_set_option() {
        // Missing: if (!current_user_can('manage_options')) wp_die();
        check_ajax_referer( 'ecwid_ajax_nonce', 'nonce' ); // Nonce check may exist, but auth check is missing
        $option = $_POST['option'];
        $value = $_POST['value'];
        update_option( $option, $value );
        wp_send_json_success();
    }
    
  5. Sink: update_option() or ecwid_update_option() is called with user-supplied data.

4. Nonce Acquisition Strategy

The Ecwid plugin typically localizes its settings and nonces for the admin environment. Even a Subscriber can access the dashboard (/wp-admin/index.php), where common plugin scripts are often enqueued.

  1. Identify the JS Object: Ecwid often uses ecwid_admin_params or ecwid_vars.
  2. Shortcode/Page Setup: If the nonce is only loaded on the Ecwid settings page (usually restricted), check if it's also enqueued on the store frontend via a shortcode.
    • Create a page: wp post create --post_type=page --post_status=publish --post_content='[ecwid_store]'
  3. Extraction:
    • Navigate to the page/dashboard as a Subscriber.
    • Execute: browser_eval("window.ecwid_vars?.nonce") or browser_eval("window.ecwid_admin_params?.nonce").
    • Verification: Grep the source code for wp_localize_script to find the exact variable name:
      grep -rn "wp_localize_script" wp-content/plugins/ecwid-shopping-cart/

5. Exploitation Strategy

The goal is to modify the ecwid_store_id to an attacker-controlled ID.

  • Step 1: Create a Subscriber user and log in.
  • Step 2: Extract the ecwid_ajax_nonce using the strategy in Section 4.
  • Step 3: Send the malicious AJAX request.
    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Content-Type: application/x-www-form-urlencoded
    • Payload:
      action=ecwid_set_option&nonce=[EXTRACTED_NONCE]&option=ecwid_store_id&value=13371337
      
  • Step 4: Verify the response is {"success":true}.

6. Test Data Setup

  1. Plugin Installation: Ensure Ecwid Shopping Cart <= 7.0.5 is installed and active.
  2. Configuration: Run the initial setup so that a legitimate ecwid_store_id is present in the database.
  3. Attacker Account:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  4. Nonce Page: Create a public page containing the Ecwid store shortcode to ensure scripts load:
    wp post create --post_type=page --post_title="Store" --post_status=publish --post_content='[ecwid_store]'

7. Expected Results

  • The AJAX request should return a successful status code (200 OK) and a JSON success message.
  • The WordPress database will be updated, changing the ecwid_store_id option from its original value to 13371337.
  • The storefront (frontend) will now attempt to load the Ecwid store associated with ID 13371337 instead of the original owner's store.

8. Verification Steps

  1. Database Check:
    wp option get ecwid_store_id
    Expected Output: 13371337
  2. Audit Logs (Optional): If a security log is present, it will show the option update triggered by the Subscriber user.

9. Alternative Approaches

If ecwid_set_option is not the vulnerable action, investigate these alternatives:

  • Action: ecwid_ajax_reconnect — Can an attacker trigger a re-authentication flow to link the site to their own Ecwid account?
  • Action: ecwid_save_settings — Does this handle a bulk array of settings?
    • Payload: action=ecwid_save_settings&settings[ecwid_store_id]=13371337&_ajax_nonce=...
  • Direct Option Update: If the plugin uses a generic update_option wrapper, try targeting other sensitive options like ecwid_api_token or ecwid_secret_key.

Grep Command to Find Target:
grep -rn "add_action.*wp_ajax" wp-content/plugins/ecwid-shopping-cart/ | grep -v "nopriv"
Look for any callback that does not call current_user_can().

Research Findings
Static analysis — not yet PoC-verified

Summary

The Ecwid Shopping Cart plugin for WordPress is vulnerable to unauthorized setting modification due to a missing capability check in its AJAX handlers. This allows authenticated attackers with subscriber-level permissions to change sensitive configurations, such as the Ecwid Store ID, potentially hijacking the store's connection or redirecting revenue.

Vulnerable Code

// In ecwid-shopping-cart/lib/ecwid_ajax_functions.php (inferred from research)
add_action( 'wp_ajax_ecwid_set_option', 'ecwid_ajax_set_option' );

function ecwid_ajax_set_option() {
    // Nonce check is present, but authorization check (e.g., current_user_can) is missing
    check_ajax_referer( 'ecwid_ajax_nonce', 'nonce' );

    $option = $_POST['option'];
    $value = $_POST['value'];

    update_option( $option, $value );
    wp_send_json_success();
}

Security Fix

--- a/lib/ecwid_ajax_functions.php
+++ b/lib/ecwid_ajax_functions.php
@@ -10,6 +10,10 @@
 	public function ajax_set_option() {
 		check_ajax_referer( 'ecwid_ajax_nonce', 'nonce' );
 
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_die();
+		}
+
 		$option = $_POST['option'];
 		$value = $_POST['value'];
 
 		update_option( $option, $value );

Exploit Outline

1. Authenticate as a low-privileged user (Subscriber level or above). 2. Obtain a valid AJAX nonce ('ecwid_ajax_nonce'). This can typically be found by inspecting the storefront or admin dashboard where the plugin localizes its scripts (e.g., checking 'window.ecwid_vars' in the browser console). 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' set to 'ecwid_set_option'. 4. Include the 'nonce', the target 'option' (e.g., 'ecwid_store_id'), and the malicious 'value' (e.g., an attacker-controlled store ID) in the request body. 5. Verify that the server returns a success response and that the WordPress option in the database has been updated.

Check if your site is affected.

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