How BitFire Blocks CVE-2026-96752: Zero Spam Stored XSS

WordPress vulnerability research

BitFire's FREE WAF and Bot Protection stop the unauthenticated Contact Form 7 POST that plants stored XSS in Zero Spam's admin Detection Log.

Unauthenticated High severity (CVSS 7.2) Admin session script execution Stored cross-site scripting
BitFire · Vulnerability advisoryResearch published
AdvisoryCVE-2026-96752
ComponentZero Spam for WordPress
Relevant sourcecore/class-utilities.php (Utilities::sanitize_array), includes/class-db.php, includes/templates/admin-modal-details.php
Executive summary

What WordPress administrators need to know

Zero Spam for WordPress — 20,000+ active installs — is vulnerable to stored cross-site scripting through version 5.7.10. An unauthenticated attacker submits a crafted Contact Form 7 form whose bracket-syntax field names become nested POST array keys carrying web scripts. Zero Spam's sanitizer inspects values but never keys, so the markup survives, is stored in the zerospam_log table when the submission is flagged as spam, and executes when a manage_options administrator opens the entry's details modal. BitFire FREE stops it at the request layer: Bot Protection blocks the automated POST, and the WAF inspects the payload for script injection before WordPress runs vulnerable code.

At a glance

Key facts

  • Unauthenticated attackers inject script markup through nested Contact Form 7 POST array keys.
  • Zero Spam 5.7.10 sanitizes array values but never array keys.
  • Malicious keys persist in the zerospam_log.submission_data column as JSON.
  • Scripts execute when a manage_options administrator opens the Detection Log details modal.
  • Fixed in 5.7.11 by key sanitization plus esc_html() output escaping.
  • BitFire Bot Protection blocks the automated POST; the WAF inspects its payload for script injection.
01
Vulnerability overview

Understand the exposure

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

Affected componentZero Spam for WordPress
Potential reach20,000+ installations
Attack techniquestored cross-site scripting
Published2026-09-24
BitFire stops this attack before WordPress runs: Bot Protection rejects the automated POST and the WAF inspects the payload for script injection — the poisoned keys never reach the Detection Log, and the admin-facing script execution never happens.
02
Technical analysis

How the vulnerability works

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

How Nested POST Keys Become Admin-Facing Script

Zero Spam hooks Contact Form 7's wpcf7_validate filter and passes the entire $_POST array through Utilities::sanitize_array(). That function sanitizes values only — never keys. PHP turns bracket-syntax field names into nested array keys, so script markup hidden in a key name survives sanitization untouched. The path is reachable wherever the plugin's Contact Form 7 protection and detection logging are enabled — recommended defaults — and a submission is flagged as spam by simply failing the plugin's JavaScript token check. DB::log() then re-runs the same key-blind sanitizer and writes the JSON-encoded details into the zerospam_log table. The Detection Log details modal, rendered on a manage_options admin page, echoes that nested-array JSON unescaped — and the stored script executes in the administrator's authenticated browser session, persisting until the log entry is purged or rotated.

BitFire FREE Blocks It Before WordPress Runs

This attack arrives as an automated, unauthenticated form POST — exactly where BitFire FREE stops it. BitFire Bot Protection classifies the request before any vulnerable WordPress code executes: unknown and restricted bots cannot submit forms, POST data, or call sensitive endpoints, and clients presenting as browsers must pass lightweight JavaScript verification that real browsers normally pass while scripts and fake browsers often fail. BitFire's WAF inspects what the request contains — form fields and POST bodies — and detects malicious JavaScript injection, including common evasion patterns. Because the exploit's markup must ride inside the POST body, it crosses the WAF's inspection boundary. Both controls ship in BitFire FREE for eligible non-commercial websites; commercial sites need an appropriate commercial license. Allowed bots bypass bot restrictions — never WAF enforcement.

Fixed in 5.7.11: Sanitize Keys, Escape Output

Zero Spam 5.7.11 breaks the chain at two layers. Utilities::sanitize_array() now sanitizes string keys with sanitize_text_field() at every nesting level and rebuilds the array, so raw markup never reaches the database; the rewrite also fixes a latent bug where recursive calls dropped the requested sanitizer type. The Detection Log details modal now wraps its JSON output in esc_html(), which neutralizes log entries stored before the upgrade as well. Update immediately — every version through 5.7.10 keeps this stored-script path open.

If Your Site Was Affected, Investigate for Persistence.

Patching closes the known path; it does not undo a compromise that already happened. An administrator who opened a poisoned log entry ran attacker-controlled scripts in their authenticated session, and attackers rarely stop at one foothold. Run BitFire Threat Hunter, a thorough post-compromise investigation that uncovers backdoor WordPress administrator accounts, hidden database triggers, long-running PHP processes, and droppers that can restore malware or reinfect the site. Remove every persistence mechanism it finds, then rotate administrator and other relevant credentials. A clean-looking Detection Log is not proof your site is clean.

Stop the Next Attack at the Request Layer

Zero Spam's flaw proves a simple point: anything a stranger can POST to your site eventually gets read by an admin. BitFire stops the attack where it starts — Bot Protection shuts out automated form submissions and the WAF inspects the payload before WordPress processes it, behavior-based controls that stop even unknown CVEs. Update Zero Spam to 5.7.11 or later, run Threat Hunter if the vulnerable version was ever live, and put BitFire in front of the next attack. Start with BitFire FREE today.

03
Source review

Vulnerable and fixed code

The relevant source is located in core/class-utilities.php (Utilities::sanitize_array), includes/class-db.php, includes/templates/admin-modal-details.php.

BeforeVulnerable behavior
// 5.7.10 — core/class-utilities.php: values are sanitized, keys never are.
foreach ( $array as $key => &$value ) {
    // $key is untouched — attacker markup in nested keys survives verbatim.
}

// includes/templates/admin-modal-details.php — unescaped nested-array output:
<?php echo wp_json_encode( $value ); ?>
AfterCorrected behavior
// 5.7.11 — core/class-utilities.php: string keys are sanitized at every depth.
$key = is_string( $key ) ? sanitize_text_field( $key ) : $key;

// includes/templates/admin-modal-details.php — defense-in-depth output escaping:
<?php echo esc_html( wp_json_encode( $value ) ); ?>
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 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 →