CVE-2026-6405

Anomify AI <= 0.3.6 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Anomify AI – Anomaly Detection and Alerting plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) leading to Stored Cross-Site Scripting (XSS) in versions up to and including 0.3.6. This is due to missing nonce verification on the settings page handler and insufficient output escaping in the admin_options.php template. The settings form includes no wp_nonce_field() and the handler performs no check_admin_referer() check, meaning any cross-origin POST can modify plugin settings. The API key field is sanitized only with sanitize_text_field(), which strips HTML tags but does not encode double-quote characters; the value is then rendered into an HTML attribute via bare echo without esc_attr(), allowing a double-quote attribute-escape payload to survive both sanitization and storage. This makes it possible for unauthenticated attackers to inject arbitrary web scripts by tricking a logged-in administrator into visiting a malicious page that submits a forged request, storing the payload in the database and causing it to execute in the administrator's browser whenever the plugin settings page is visited.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=0.3.6
PublishedMay 19, 2026
Last updatedMay 20, 2026
Affected pluginanomify
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional attack payloads, or technical guides for exploiting specific vulnerabilities in software. I can, however, explain the theoretical mechanics of Cross-Site Request Forgery (CSRF) and Stored Cross-S…

Show full research plan

I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional attack payloads, or technical guides for exploiting specific vulnerabilities in software. I can, however, explain the theoretical mechanics of Cross-Site Request Forgery (CSRF) and Stored Cross-Site Scripting (XSS) within the WordPress ecosystem and how developers can defend against these vulnerabilities.

Theoretical Mechanics of the Vulnerability Chain

The scenario described involves a chain where a CSRF vulnerability is used to deliver a Stored XSS payload.

1. Cross-Site Request Forgery (CSRF) in WordPress

CSRF occurs when a web application processes a state-changing request (like saving settings) without verifying that the request was intentionally initiated by the authenticated user.

In WordPress, protection against CSRF is primarily handled through "Nonces." These are security tokens unique to a specific user, action, and time window.

  • Vulnerability: A plugin is vulnerable if its admin settings handlers (typically hooked to admin_init or admin_post_) do not call verification functions like check_admin_referer() or wp_verify_nonce().
  • Exploitation: An attacker tricks a logged-in administrator into visiting a malicious website. That website contains a hidden form or a script that sends a POST request to the target site’s settings page. Since the administrator is authenticated, the browser includes their session cookies, and the plugin processes the request as if the administrator made it.

2. Stored Cross-Site Scripting (XSS) via Attribute Injection

XSS occurs when user-controlled input is rendered on a page without proper sanitization or escaping. Stored XSS means the payload is saved in the database (e.g., in the wp_options table).

  • Sanitization vs. Escaping:
    • sanitize_text_field() is a common WordPress function that strips HTML tags and line breaks. However, it does not necessarily encode double quotes (").
    • If a value sanitized this way is later rendered inside an HTML attribute (e.g., <input value="VALUE_HERE">) without being passed through esc_attr(), it is vulnerable.
  • Attribute Breakout: An attacker can provide a value like "><script>alert(1)</script>. The first " closes the attribute, and the > closes the HTML tag, allowing the subsequent script to be executed by the browser.

Defensive Best Practices

To prevent these vulnerabilities, WordPress developers should adhere to the following security patterns:

  1. Implement Nonce Verification: Every form that changes data should include a nonce field using wp_nonce_field(). The corresponding handler must verify the nonce using check_admin_referer('action_name', 'nonce_name').
  2. Capability Checks: Always verify that the user has the necessary permissions to perform the action using current_user_can('manage_options').
  3. Sanitize on Input: Use the most restrictive sanitization function possible (e.g., sanitize_key(), absint(), or sanitize_text_field()) before saving data to the database.
  4. Escape on Output: This is the most critical defense against XSS. Always use late escaping. When rendering data into an HTML attribute, use esc_attr(). When rendering data as HTML content, use esc_html().

For further information on securing WordPress plugins, I recommend consulting the WordPress Plugin Handbook's Security section.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Anomify AI plugin suffers from a CSRF vulnerability that allows attackers to update plugin settings because the administration panel lacks nonce verification. This is chained with a Stored XSS vulnerability where the API key setting is sanitized with sanitize_text_field() but rendered without esc_attr(), allowing an attacker to inject script tags or malicious attributes into the plugin's settings page.

Vulnerable Code

// Handler likely in a core plugin file or admin_options.php
if (isset($_POST['anomify_api_key'])) {
    // Vulnerable: missing check_admin_referer() for CSRF protection
    update_option('anomify_api_key', sanitize_text_field($_POST['anomify_api_key']));
}

---

// View in admin_options.php
$api_key = get_option('anomify_api_key');
// Vulnerable: missing esc_attr() allows attribute escape
echo '<input type="text" name="anomify_api_key" value="' . $api_key . '">';

Security Fix

--- a/admin_options.php
+++ b/admin_options.php
@@ -1,10 +1,13 @@
-if (isset($_POST['anomify_api_key'])) {
+if (isset($_POST['anomify_api_key']) && check_admin_referer('anomify_save_settings', 'anomify_nonce')) {
+    if (!current_user_can('manage_options')) { wp_die(); }
     update_option('anomify_api_key', sanitize_text_field($_POST['anomify_api_key']));
 }
 
 <form method="post">
+    <?php wp_nonce_field('anomify_save_settings', 'anomify_nonce'); ?>
     <table>
         <tr>
             <th>API Key</th>
-            <td><input type="text" name="anomify_api_key" value="<?php echo get_option('anomify_api_key'); ?>"></td>
+            <td><input type="text" name="anomify_api_key" value="<?php echo esc_attr(get_option('anomify_api_key')); ?>"></td>
         </tr>
     </table>
 </form>

Exploit Outline

The exploit is executed by crafting a malicious HTML page containing a hidden form that targets the WordPress admin settings page for Anomify AI. The form's payload includes a field for 'anomify_api_key' set to a value like '"><script>alert(1)</script>'. Because the plugin lacks a CSRF nonce (wp_nonce_field) and fails to verify one (check_admin_referer), the administrator's browser will automatically submit the request when they visit the malicious page while logged into WordPress. The 'sanitize_text_field' function does not encode the double-quote characters, allowing the payload to break out of the HTML attribute context. When the administrator subsequently visits the plugin settings page, the injected script executes in their browser context.

Check if your site is affected.

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