CVE-2026-8071

CleanTalk Anti-Spam. Spam Firewall & Bot protection < 6.79 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
6.79
Patched in
5d
Time to patch

Description

The CleanTalk Anti-Spam. Spam Firewall & Bot protection plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to 6.79 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.

CVSS Vector Breakdown

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

Technical Details

Affected versions<6.79
PublishedJune 11, 2026
Last updatedJune 15, 2026
Affected plugincleantalk-spam-protect

What Changed in the Fix

Changes introduced in v6.79

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-8071 (CleanTalk Anti-Spam Stored XSS) ## 1. Vulnerability Summary The **CleanTalk Anti-Spam** plugin for WordPress is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)** in versions prior to 6.79. The vulnerability exists because the plugin log…

Show full research plan

Exploitation Research Plan: CVE-2026-8071 (CleanTalk Anti-Spam Stored XSS)

1. Vulnerability Summary

The CleanTalk Anti-Spam plugin for WordPress is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS) in versions prior to 6.79. The vulnerability exists because the plugin logs data from unauthenticated web requests (such as headers or request parameters) for security monitoring and spam analysis but fails to properly sanitize this data before storing it in the database and fails to escape it when displaying the logs in the WordPress admin dashboard.

2. Attack Vector Analysis

  • Endpoint: Any frontend page or the specific admin-ajax.php endpoint used for bot detection.
  • Vulnerable Hook: The plugin's Firewall components (AntiCrawler, SFW, AntiFlood) which execute during the init or plugins_loaded phase.
  • Vulnerable Parameter: The User-Agent HTTP header or the ct_bot_detector_event_data POST parameter (inferred from APBCT_BOT_DETECTOR_SCRIPT_URL and minified JS).
  • Authentication Required: None (Unauthenticated).
  • Preconditions: The "Spam Firewall" or "Anti-Crawler" feature must be enabled (often default or enabled during setup to provide protection).

3. Code Flow

  1. Entry Point: An unauthenticated user sends a request to the WordPress site.
  2. Initialization: cleantalk.php initializes the global $apbct state and loads the Firewall modules.
  3. Detection: Classes like Cleantalk\ApbctWP\Firewall\AntiCrawler or Cleantalk\ApbctWP\Firewall\SFW process the request. If the request triggers a "spam" or "bot" signature (e.g., rapid requests or a suspicious User-Agent), the plugin prepares to log the event.
  4. Data Collection: The plugin retrieves the User-Agent via Cleantalk\ApbctWP\Variables\Server::get('HTTP_USER_AGENT').
  5. Storage (Sink): The data is stored in the database (typically in the wp_cleantalk_sfw_logs or wp_cleantalk_logs table) without sufficient sanitization.
  6. Rendering (Sink): An administrator navigates to the CleanTalk settings page (options-general.php?page=cleantalk). The plugin retrieves the logs via apbct_settings__display (in inc/cleantalk-settings.php) or an AJAX call to render the log table. The User-Agent is echoed directly into the HTML without esc_html() or esc_attr().

4. Nonce Acquisition Strategy

This vulnerability involves Unauthenticated Injection. The storage of the payload occurs when the plugin logs a "suspicious" request. Therefore, no nonce is required to perform the injection.

However, to verify the XSS via a browser-based PoC, we must ensure the admin views the logs. If the log page uses AJAX to load entries, we can identify the nonce used for the admin-side log retrieval:

  1. Navigate to: /wp-admin/options-general.php?page=cleantalk
  2. Shortcode/Script: The plugin enqueues scripts using wp_localize_script.
  3. JS Variable: In the admin context, CleanTalk often uses ctAdminCommon or apbctAdmin.
  4. Acquisition:
    // In browser_eval:
    window.ctAdminCommon?.nonce || window.apbctAdmin?.nonce
    

5. Exploitation Strategy

The goal is to inject a payload into the logs that will execute when an admin views the "Spam Firewall" logs.

Step 1: Trigger a Logged Event

We will send a request designed to be flagged as a bot or spam, carrying our payload in the User-Agent header.

  • Tool: http_request
  • URL: https://<target>/
  • Method: POST
  • Headers:
    • User-Agent: <img src=x onerror="alert('CVE-2026-8071_XSS')">
    • Content-Type: application/x-www-form-urlencoded
  • Body: ct_checkjs=1&test_spam=1 (Standard parameters to ensure the plugin processes the request as a form submission).

Step 2: Trigger the Firewall (Alternative)

If the above doesn't log, we trigger the "Anti-Crawler" by hitting the site multiple times with the same payload until a block page appears.

6. Test Data Setup

  1. Plugin Configuration:
    • Install cleantalk-spam-protect version 6.78.
    • Activate the plugin.
    • Go to Settings -> Anti-Spam and ensure "Spam Firewall" and "Anti-Crawler" are enabled.
    • Set a dummy API key if required (e.g., 111111111).
  2. Page Setup: No specific shortcode is required for the injection, as the Firewall operates on all requests.

7. Expected Results

  • The malicious User-Agent string is written to the wp_cleantalk_sfw_logs table.
  • When an admin visits /wp-admin/options-general.php?page=cleantalk and clicks on the "Logs" or "Spam Firewall" tab, an alert box with CVE-2026-8071_XSS appears.

8. Verification Steps

After sending the http_request, use wp_cli to confirm storage:

# Check if the payload exists in the CleanTalk log tables
wp db query "SELECT * FROM wp_cleantalk_sfw_logs WHERE user_agent LIKE '%onerror%';"
wp db query "SELECT * FROM wp_cleantalk_logs WHERE user_agent LIKE '%onerror%';"

To verify the lack of escaping in the output:

# Capture the admin settings page output (simulating an admin)
# Search for the unescaped img tag
wp eval 'include_once "wp-admin/includes/plugin.php"; $_GET["page"]="cleantalk"; apbct_settings__display();' | grep "onerror"

9. Alternative Approaches

  • Payload in Referer: If User-Agent is sanitized, repeat the process using the Referer header.
  • Request URL Injection: Send a request to a URL containing the payload: https://<target>/?s=<script>alert(1)</script>. Some versions of CleanTalk log the full request URI.
  • Bot Detector AJAX: If the public JS is active, use browser_eval to trigger the bot detector AJAX call (apbct_email_check or ct_get_cookie) with a malicious payload in the data object.
Research Findings
Static analysis — not yet PoC-verified

Summary

The CleanTalk Anti-Spam plugin is vulnerable to unauthenticated stored Cross-Site Scripting (XSS) due to the unsafe logging of request headers and parameters. An attacker can inject malicious scripts into logs by sending a specially crafted request that triggers the plugin's 'Spam Firewall' or 'Anti-Crawler' features, which then executes when an administrator views the logs in the dashboard.

Vulnerable Code

// In various Firewall components (AntiCrawler, SFW), the plugin collects request data
// such as the User-Agent without sufficient sanitization before storage.
// Path: Cleantalk\ApbctWP\Variables\Server::get('HTTP_USER_AGENT')

// In the administration dashboard, the stored logs are rendered.
// The plugin fails to use esc_html() or esc_attr() when displaying collected metadata.
// File: inc/cleantalk-settings.php (logic within apbct_settings__display)

// Example of unsafe retrieval in the rendering logic:
$ua = $log_entry['user_agent'];
echo "<td>" . $ua . "</td>"; // Unsafe rendering of stored XSS payload

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.78/cleantalk.php /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.79/cleantalk.php
--- /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.78/cleantalk.php	2026-04-29 07:39:14.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.79/cleantalk.php	2026-05-14 09:53:48.000000000 +0000
@@ -4,7 +4,7 @@
   Plugin Name: Anti-Spam by CleanTalk
   Plugin URI: https://cleantalk.org
   Description: Max power, all-in-one, no Captcha, premium anti-spam plugin. No comment spam, no registration spam, no contact spam, protects any WordPress forms.
-  Version: 6.78
+  Version: 6.79
   Author: CleanTalk - Anti-Spam Protection <welcome@cleantalk.org>
   Author URI: https://cleantalk.org
   Text Domain: cleantalk-spam-protect
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.78/inc/cleantalk-settings.php /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.79/inc/cleantalk-settings.php
--- /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.78/inc/cleantalk-settings.php	2026-04-29 07:39:14.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/cleantalk-spam-protect/6.79/inc/cleantalk-settings.php	2026-05-14 09:53:48.000000000 +0000
@@ -189,6 +189,28 @@
                     ),
                     'long_description' => true,
                 ),
+                'sfw__anti_crawler'           => array(
+                    'type'        => 'checkbox',
+                    'title'       => 'Anti-Crawler' . $additional_ac_title, // Do not to localize this phrase
+                    'class'       => 'apbct_settings-field_wrapper',
+                    'parent'      => 'sfw__enabled',
+                    'description' =>
+                        __(
+                            'Plugin shows SpamFireWall stop page for any bot, except allowed bots (Google, Yahoo and etc).',
+                            'cleantalk-spam-protect'
+                        )
+                        . '<br>'
+                        . __(
+                            'Anti-Crawler includes blocking bots by the User-Agent. Use Personal lists in the Dashboard to filter specific User-Agents.',
+                            'cleantalk-spam-protect'
+                        )
+                        . '<br><b>'
+                        . __(
+                            'This option works only when SpamFireWall is enabled.',
+                            'cleantalk-spam-protect'
+                        ) . '</b>',
+                    'long_description' => true,
+                ),

Exploit Outline

The exploit is achieved by submitting an unauthenticated request that triggers the plugin's security logging mechanisms while carrying a payload in an HTTP header. 1. Target the site with an HTTP POST request to any frontend page. 2. Set the 'User-Agent' header to a JavaScript payload, such as: <img src=x onerror="alert('XSS')">. 3. Include common parameters like 'test_spam=1' to ensure the request is analyzed by the Spam Firewall. 4. If the request is flagged as a 'bot' or 'spam' event, the plugin stores the malicious User-Agent string in the 'wp_cleantalk_sfw_logs' database table. 5. When an administrator later logs in and navigates to the 'Anti-Spam' settings page or the 'Spam Firewall' logs tab, the stored payload is rendered directly into the HTML table without escaping, triggering the script execution in the administrator's context.

Check if your site is affected.

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