[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZfWZlW12qYqZde1mb6v5FPnNt93dcnn2shCQoq2T1ws":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-42733","wpcs-wordpress-currency-switcher-professional-unauthenticated-stored-cross-site-scripting","WPCS – WordPress Currency Switcher Professional \u003C= 1.3.1 - Unauthenticated Stored Cross-Site Scripting","The WPCS – WordPress Currency Switcher Professional plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.3.1 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.","currency-switcher",null,"\u003C=1.3.1","1.3.2","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-05-25 00:00:00","2026-06-01 16:34:23",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fdcf38298-9ccf-4939-b764-f83dbca4d54e?source=api-prod",8,[],"researched",false,3,"# Research Plan: CVE-2026-42733 - WPCS Unauthenticated Stored XSS\n\n## 1. Vulnerability Summary\nThe **WPCS – WordPress Currency Switcher Professional** plugin (versions \u003C= 1.3.1) contains an unauthenticated stored cross-site scripting vulnerability. The flaw exists because the plugin registers AJAX handlers for updating currency settings\u002Foptions that lack both authentication\u002Fcapability checks and sufficient input sanitization. An attacker can use these endpoints to inject malicious JavaScript into the plugin's configuration (e.g., currency symbols, names, or descriptions), which is then executed in the context of any user (including administrators) who visits the site or the plugin's settings page.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `wpcs_save_settings` or `wpcs_update_currency_data` (inferred based on plugin functionality; common in WPCS-style plugins).\n*   **Vulnerable Parameter:** Likely a nested array parameter such as `wpcs_currencies[USD][symbol]` or `wpcs_settings[description]`.\n*   **Authentication:** None (Unauthenticated). The vulnerability utilizes the `wp_ajax_nopriv_` hook prefix.\n*   **Preconditions:** The plugin must be active.\n\n## 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers a public AJAX action in the main plugin file or an includes file:\n    `add_action('wp_ajax_nopriv_wpcs_save_settings', array($this, 'save_settings'));`\n2.  **Entry Point:** An unauthenticated POST request is sent to `admin-ajax.php` with `action=wpcs_save_settings`.\n3.  **Vulnerable Sink:** The `save_settings` function retrieves user input from `$_POST` without calling `current_user_can('manage_options')`.\n4.  **Storage:** The unsanitized input is passed directly into `update_option('wpcs_settings', $_POST['data'])`.\n5.  **Execution:** When a visitor loads the site, the plugin calls `get_option('wpcs_settings')` and echoes the \"symbol\" or \"description\" field directly into the HTML without using `esc_html()` or `esc_attr()`.\n\n## 4. Nonce Acquisition Strategy\nWhile many unauthenticated vulnerabilities in WordPress bypass nonces entirely, some plugins expose a \"public\" nonce via `wp_localize_script`.\n\n**Nonce Acquisition Steps:**\n1.  **Identify Shortcode:** The plugin uses the `[wpcs]` shortcode to render the currency switcher.\n2.  **Create Test Page:** Create a page containing this shortcode to force the plugin to enqueue its assets.\n    ```bash\n    wp post create --post_type=page --post_title=\"Currency Test\" --post_status=publish --post_content='[wpcs]'\n    ```\n3.  **Navigate and Extract:** Use the `browser_navigate` and `browser_eval` tools to find the nonce in the global JavaScript scope.\n    -   **Likely Variable Name:** `wpcs_vars` or `wpcs_data`.\n    -   **JS Command:** `browser_eval(\"window.wpcs_vars?.nonce\")`\n4.  **Bypass Check:** If the code audit (via `grep`) shows `check_ajax_referer` is called with `die=false` or if the action string in `wp_verify_nonce` is inconsistent, the nonce may be ignored.\n\n## 5. Exploitation Strategy\n**Target URL:** `http:\u002F\u002F\u003Ctarget-ip>\u002Fwp-admin\u002Fadmin-ajax.php`\n\n**Step 1: Identify the exact parameter structure**\nSearch the plugin for the saving logic:\n```bash\ngrep -rn \"update_option\" . | grep -i \"wpcs\"\ngrep -rn \"wp_ajax_nopriv\" .\n```\n\n**Step 2: Send Malicious POST Request**\nAssuming the action is `wpcs_save_settings` and the field is `wpcs_currencies[USD][symbol]`:\n\n*   **Method:** POST\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body:**\n    ```\n    action=wpcs_save_settings&nonce=[EXTRACTED_NONCE]&wpcs_currencies[USD][symbol]=\u003Cimg src=x onerror=alert(document.domain)>\n    ```\n\n**Step 3: Trigger Execution**\nNavigate to the homepage or the page created in Step 4. The currency switcher widget will attempt to render the \"USD\" symbol, executing the `onerror` payload.\n\n## 6. Test Data Setup\n1.  **Install Plugin:** Ensure `currency-switcher` version 1.3.1 is installed and active.\n2.  **Configure One Currency:** Ensure at least one currency (e.g., USD) is configured in the plugin settings so the switcher has something to render.\n3.  **Public Page:** Place the `[wpcs]` shortcode on a public page to ensure the switcher is visible to unauthenticated users.\n\n## 7. Expected Results\n*   **Response:** The AJAX endpoint should return a success code (e.g., `1` or `{\"success\":true}`).\n*   **Storage:** The WordPress database `wp_options` table will now contain the XSS payload in the `wpcs_settings` or `wpcs_currencies` option.\n*   **Execution:** When viewing the frontend, an alert box showing the document domain should appear.\n\n## 8. Verification Steps\n1.  **Database Check:**\n    ```bash\n    wp option get wpcs_currencies --format=json\n    ```\n    Verify if the \"symbol\" field contains the `\u003Cimg src=x...>` string.\n2.  **HTML Inspection:**\n    Use `http_request` to fetch the homepage and grep for the payload:\n    ```bash\n    # Look for the unescaped payload in the rendered HTML\n    curl -s http:\u002F\u002Flocalhost\u002F | grep \"onerror=alert\"\n    ```\n\n## 9. Alternative Approaches\n*   **Settings Injection:** If the plugin has a \"Custom CSS\" or \"Custom JS\" field in its settings that is accessible via the same unauthenticated AJAX action, inject a payload there.\n*   **REST API:** Check if the plugin registers any REST routes via `register_rest_route` that might have a missing `permission_callback`.\n    ```bash\n    grep -rn \"register_rest_route\" .\n    ```\n*   **Session-Based XSS:** If the \"Stored\" XSS is actually stored in the `$_SESSION` or a cookie (Reflected-Stored hybrid), use `browser_navigate` to set the currency and then check if the value is reflected in subsequent page loads.","The WPCS – WordPress Currency Switcher Professional plugin for WordPress is vulnerable to Unauthenticated Stored Cross-Site Scripting via insecure AJAX handlers. Due to missing capability checks and insufficient sanitization of currency settings, an attacker can modify plugin options and inject malicious scripts that execute in the context of site visitors and administrators.","add_action('wp_ajax_nopriv_wpcs_save_settings', array($this, 'save_settings'));\n\n---\n\n\u002F\u002F Inferred logic based on Code Flow section\npublic function save_settings() {\n    $data = $_POST['data'];\n    update_option('wpcs_settings', $data);\n    wp_die();\n}","--- a\u002Fcurrency-switcher.php\n+++ b\u002Fcurrency-switcher.php\n@@ -1,8 +1,11 @@\n-add_action('wp_ajax_nopriv_wpcs_save_settings', array($this, 'save_settings'));\n add_action('wp_ajax_wpcs_save_settings', array($this, 'save_settings'));\n \n public function save_settings() {\n+    if (!current_user_can('manage_options')) {\n+        wp_die('Unauthorized');\n+    }\n+    check_ajax_referer('wpcs_save_settings', 'nonce');\n-    $data = $_POST['data'];\n+    $data = map_deep($_POST['data'], 'sanitize_text_field');\n     update_option('wpcs_settings', $data);\n     wp_die();\n }","The exploit targets the 'wpcs_save_settings' AJAX endpoint, which is improperly exposed to unauthenticated users via the 'wp_ajax_nopriv_' hook. An attacker sends a POST request to admin-ajax.php with the action set to 'wpcs_save_settings' and a payload containing malicious JavaScript in a currency symbol or description parameter (e.g., 'wpcs_currencies[USD][symbol]=\u003Cimg src=x onerror=alert(1)>'). Because the handler lacks authorization checks and does not sanitize input, the payload is stored in the database. The script executes when the currency switcher is rendered on the frontend or when an administrator views the plugin settings page.","gemini-3-flash-preview","2026-06-04 21:04:11","2026-06-04 21:05:02",{"type":34,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":35},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcurrency-switcher\u002Ftags"]