CVE-2022-3302 vulnerability and BitFire protection

How BitFire Blocks CVE-2022-3302: CleanTalk Anti-Spam SQL Injection

WordPress vulnerability research

BitFire's FREE WAF blocks the CVE-2022-3302 SQL injection in the CleanTalk Anti-Spam plugin before vulnerable code runs.

Administrator session required High severity (CVSS 7.2) Database compromise SQL injection
BitFire · Vulnerability advisoryResearch published
AdvisoryCVE-2022-3302
ComponentAnti-Spam by CleanTalk – Spam Protection Without CAPTCHA
Relevant sourcelib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php :: removeLogs() (called from CommentsLogs::bulk_actions_handler())
Executive summary

What WordPress administrators need to know

CVE-2022-3302 is a high-severity SQL injection in the CleanTalk Anti-Spam WordPress plugin, which runs on 200,000 sites. A logged-in administrator who POSTs to the plugin's ct_check_spam_logs page reaches CommentsLogs::bulk_actions_handler(), which forwards raw $_POST['spamids'] values into removeLogs(). Those values are joined with implode() and interpolated straight into a DELETE statement, with no wp_parse_id_list() and no $wpdb->prepare(). sanitize_textarea_field() does not neutralize SQL metacharacters. Crafted array values rewrite the query against the plugin's spam-scan log table, and the vendor disclosure warns appended queries could expose sensitive database content. BitFire's FREE WAF recognizes the malicious SQL syntax in the request and blocks the exploit before vulnerable plugin code ever runs.

At a glance

Key facts

  • SQL injection through attacker-controlled $_POST['spamids'] values in the bulk log-deletion handler
  • Reachable only with a logged-in activate_plugins session and a valid bulk-spam nonce
  • removeLogs() interpolates implode(', ', $ids) into an unprepared $wpdb->query() DELETE
  • sanitize_textarea_field() on the input does not remove SQL metacharacters
  • Fixed in 5.185.1 by wp_parse_id_list() applied at both the handler and the sink
  • BitFire FREE WAF detects the injected SQL syntax in the request and blocks it before the plugin executes
01
Vulnerability overview

Understand the exposure

The affected component, attack path, and practical risk for WordPress websites.

Affected componentAnti-Spam by CleanTalk – Spam Protection Without CAPTCHA
Potential reach200000 installations
Attack techniquesql injection
Published2026-09-29
BitFire's FREE WAF inspects every request before WordPress runs, catches the malicious SQL syntax CVE-2022-3302 depends on, and blocks the exploit outright — behavior-based defense that works even before you patch.
02
Technical analysis

How the vulnerability works

Research details, affected versions, exploitation behavior, and remediation guidance.

The Vulnerability: Unescaped POST Data in a DELETE Query

The flaw sits on the plugin's 'Scan logs' admin page, registered under the ct_check_spam_logs slug. bulk_actions_handler() verifies a valid bulk-spam nonce and the activate_plugins capability, then calls removeLogs(Post::get('spamids')). Post::get() applies only sanitize_textarea_field(), which coerces nothing to integers and neutralizes no SQL syntax. The inherited Comments::removeLogs() turns the array into $ids_string with implode(', ', $ids) and concatenates it into a DELETE against the cleantalk_spamscan_logs table through an unprepared $wpdb->query() call. Untrusted POST elements therefore cross directly into SQL text construction. There is no authorization weakness — only the session's own administrator can drive the handler — but that administrator's crafted values change what the statement deletes, exactly the injection the patch confirms.

BitFire FREE WAF: The Injection Dies at the Request Layer

This exploit cannot work without malicious SQL syntax inside the POST body, and that is exactly what the BitFire FREE WAF is built to catch. BitFire inspects form data and POST bodies before WordPress or the plugin processes them, matching injection syntax and common evasion patterns. A crafted spamids payload aimed at ct_check_spam_logs is flagged and blocked at the request layer — vulnerable removeLogs() code never executes. The detection is behavior-based, not a CVE-specific signature, so unknown injection variants get the same treatment. Because the vector requires a genuine administrator session and a valid nonce, bot filtering is not the decisive layer here; payload inspection is. The WAF ships with BitFire FREE for eligible non-commercial sites, and commercial sites simply add the appropriate license.

If Your Site Was Affected, Investigate for Persistence

Version 5.185.1 routes every spamids value through wp_parse_id_list() at both the entry point and the sink, coercing each element to a positive integer so the query can only ever receive a comma-separated list of integers. Update immediately. Patching closes this path, but it does not undo a compromise that already happened: injected SQL against a live database can leave persistence behind. Run BitFire Threat Hunter to sweep for backdoor administrator accounts, hidden database triggers, long-running PHP processes, and droppers that can restore malware or reinfect the site. Remove every discovered artifact and rotate the credentials a compromised database could expose — WordPress administrator passwords and database credentials included. A clean-looking file tree proves nothing on its own; investigate before you trust the site again.

Close the Gap with BitFire

SQL injection in an anti-spam plugin is still a direct line into your database. BitFire FREE's WAF stops CVE-2022-3302 at the request layer, before a single vulnerable line runs — and the same behavior-based inspection defends against injection flaws in every other plugin you run. Patch to 5.185.1, let BitFire Threat Hunter hunt for administrator backdoors, hidden triggers, and droppers, and rotate exposed credentials. Install BitFire FREE today and make request-layer injection defense the default on every WordPress site you operate.

03
Source review

Vulnerable and fixed code

The relevant source is located in lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php :: removeLogs() (called from CommentsLogs::bulk_actions_handler()).

BeforeVulnerable behavior
// lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsLogs.php (5.185)
$this->removeLogs(Post::get('spamids'));

// lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php (5.185) — inherited sink
$ids_string = implode(', ', $ids);
$wpdb->query("DELETE FROM " . APBCT_SPAMSCAN_LOGS . " WHERE ID IN ($ids_string)");
AfterCorrected behavior
// lib/Cleantalk/ApbctWP/FindSpam/ListTable/CommentsLogs.php (5.185.1)
$spam_ids = wp_parse_id_list(Post::get('spamids'));
$this->removeLogs($spam_ids);

// lib/Cleantalk/ApbctWP/FindSpam/ListTable/Comments.php (5.185.1) — defense-in-depth sink
$spam_ids = wp_parse_id_list($ids);
$ids_string = implode(', ', $spam_ids);
04
Zero-day protection

Protection from the first exploit request

BitFire protects WordPress servers on day zero—before a vulnerability is publicly known and before other vendors have time to develop signatures or patches.

01 · VerifyStop unknown clients

Bot controls and browser verification stop untrusted automated clients before previously unknown exploit code reaches WordPress.

02 · DetectBlock malicious behavior

General WAF protections identify dangerous request behavior and hostile payloads without waiting for a vulnerability-specific signature.

03 · PreventContain attacks at runtime

RASP follows execution inside PHP and prevents unauthorized changes to protected files, accounts, and database content.

BitFire · WordPress protectionZero-day ready
BitFire zero-day WordPress vulnerability protection
BitFire combines verified-client controls, behavior-based WAF detection, and runtime RASP enforcement to protect WordPress before an exploit has a name, CVE, signature, or vendor patch.
About the author

Cory Marsh

Cory has more than 20 years of internet security experience and is a lead developer on the BitFire project.

Read BitFire security research →
Protect your WordPress website

Add protection before the next exploit arrives.

BitFire combines bot controls, request inspection, malware detection, and runtime protection in one WordPress security platform.

Protect my site free →