CVE-2026-1490 vulnerability and BitFire protection

How BitFire Blocks CVE-2026-1490: CleanTalk Anti-Spam Authorization Bypass Via…

WordPress vulnerability research

BitFire stops CVE-2026-1490 twice: FREE Bot Protection blocks the scripted exploit delivery and BitFire PRO RASP blocks the unauthorized plugin install.

Unauthenticated CVSS 9.8 Critical Remote Code Execution Authorization Bypass via PTR Spoofing
BitFire · Vulnerability advisoryResearch published
AdvisoryCVE-2026-1490
ComponentAnti-Spam by CleanTalk – Spam Protection Without CAPTCHA
Relevant sourcelib/Cleantalk/Common/Helper.php: Helper::ipResolve() -> lib/Cleantalk/ApbctWP/RemoteCalls.php: RemoteCalls::checkWithoutToken()
Executive summary

What WordPress administrators need to know

CleanTalk Anti-Spam 6.71 and earlier trusts an unverified reverse-DNS hostname when authorizing tokenless remote calls. From any connection whose PTR record they control, an unauthenticated attacker can satisfy the plugin's NOC authorization branch on sites with an invalid or missing API key, plant an API key they know, and invoke privileged install_plugin and activate_plugin actions. WordPress then downloads, installs, and activates an attacker-chosen plugin package, putting executable attacker code on the server: remote code execution, CVSS 9.8. BitFire FREE Bot Protection blocks the scripted request before WordPress runs it, and BitFire PRO RASP blocks the unauthorized plugin install itself. Version 6.72 fixes the flaw with Forward-Confirmed reverse DNS.

At a glance

Key facts

  • Unauthenticated flaw: the remote-call handler runs on the public init hook with every parameter taken from $_REQUEST.
  • Root cause: 6.71 accepted the client IP's raw reverse-DNS (PTR) hostname — attacker-controlled — as CleanTalk NOC identity.
  • Reachability: the tokenless NOC branch is open only while the site's CleanTalk API key is invalid or missing.
  • Impact: arbitrary wordpress.org plugin installation and activation puts attacker-selected executable PHP on the server — CVSS 9.8 remote code execution.
  • Fixed in 6.72 with Forward-Confirmed reverse DNS; no valid token can be derived after the patch.
  • BitFire FREE Bot Protection blocks exploit delivery; BitFire PRO RASP blocks the unauthorized plugin PHP write.
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 techniqueauthorization bypass via ptr spoofing
Published2026-10-09
BitFire kills CVE-2026-1490 twice: FREE Bot Protection blocks the spoofed remote call before WordPress runs it, and BitFire PRO RASP stops the unauthorized plugin PHP from ever landing on your server.
02
Technical analysis

How the vulnerability works

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

Unauthenticated Authorization Bypass to Arbitrary Plugin Installation

CleanTalk's remote-call handler registers on WordPress's public init hook, so every visitor reaches it unauthenticated, and every parameter — action, plugin name, token, API key, target plugin — arrives from $_REQUEST. RemoteCalls::perform() authorizes a call with a valid token or through checkWithoutToken() plus a tokenless action allow-list. In 6.71, checkWithoutToken() treated the raw reverse-DNS (PTR) hostname of the connecting IP as proof of CleanTalk NOC identity, with no forward confirmation. PTR records belong to whoever controls the address — routinely a rented server's operator. On sites whose CleanTalk API key is invalid or missing, one unverified hostname satisfies the NOC branch: an attacker-controlled value crossing straight into an authorization decision.

BitFire FREE Bot Protection Stops the Exploit Before WordPress Runs It

Every step of this chain travels in scripted, unauthenticated HTTP requests — precisely the traffic BitFire FREE Bot Protection refuses. Unknown or restricted automated clients are barred from POSTing data and calling sensitive plugin endpoints, so the spoofed NOC remote call never reaches checkWithoutToken(). Known attack and scanning tools are blocked outright, and clients presenting as browsers must pass JavaScript browser verification that scripts and fake browsers routinely fail. The chain dies at delivery: no request, no authorization decision, no planted key. The documented caveat: explicitly allowlisted bots and successfully verified real browsers are not categorically stopped — which is exactly why a second layer matters.

BitFire PRO RASP Blocks the Unauthorized Plugin Install

If a crafted request ever slipped past request filtering, BitFire PRO RASP evaluates what WordPress attempts, not what the request looks like. Its filesystem protection inspects PHP-file writes and blocks unauthorized creation or modification of PHP, explicitly including plugin installation payloads. The moment apbct_rc__install_plugin() drives CleantalkUpgrader to unpack attacker-selected code under wp-content/plugins, RASP stops the write: no attacker PHP reaches disk, so activate_plugins() has nothing hostile to arm. This enforcement sits at the protected operation, requires no CVE signature, and applies to any unauthenticated or non-administrator request pursuing the same outcome. Runtime blocking is BitFire PRO — enable RASP filesystem protection in production.

Update to 6.72: Forward-Confirmed DNS Breaks the Chain at Entry

Version 6.72 rewrites Helper::ipResolve() to perform Forward-Confirmed reverse DNS: validate the IP, take the PTR hostname, resolve it forward, and require the original IP among the answers — every failure returns false. checkWithoutToken() now rejects an unresolvable client and demands a strictly verified NOC hostname. With PTR spoofing dead, the tokenless NOC branch is unreachable, no attacker-known API key can be planted, and no valid remote-call token can be derived for the privileged plugin actions. Sites running 6.71 or earlier should update immediately; there is no configuration workaround for a flaw this early in the authorization chain.

If Your Site Was Affected, Investigate for Persistence

Patching closes CVE-2026-1490; it does not undo an earlier compromise. An attacker who completed the chain had working plugin installation on your server — assume persistence and hunt for it. BitFire Threat Hunter performs a thorough post-compromise investigation: it discovers backdoor WordPress administrator accounts, hidden database triggers, long-running PHP processes, and droppers that can restore malware or reinfect the site. Run it on every site that ran 6.71 or earlier, remove every item it finds, and rotate WordPress salts and administrator credentials. A quiet admin screen is not evidence of a clean site.

Hold the Line with BitFire

CVE-2026-1490 turns a spam plugin into an unauthenticated software installer, but BitFire breaks it at two independent points: FREE Bot Protection refuses the scripted delivery before WordPress executes vulnerable code, and BitFire PRO RASP blocks the unauthorized plugin PHP from ever reaching disk. Install BitFire, keep the FREE bot and request defenses on, add PRO RASP for runtime enforcement, and run Threat Hunter if 6.71 ever touched your server. Update to CleanTalk 6.72 today — then let BitFire hold the line against the next one.

03
Source review

Vulnerable and fixed code

The relevant source is located in lib/Cleantalk/Common/Helper.php: Helper::ipResolve() -> lib/Cleantalk/ApbctWP/RemoteCalls.php: RemoteCalls::checkWithoutToken().

BeforeVulnerable behavior
public static function ipResolve($ip)
{
    if (self::ipValidate($ip)) {
        $url = gethostbyaddr($ip);
        if ($url) {
            return $url;
        }
    }

    return $ip;
}
AfterCorrected behavior
public static function ipResolve($ip)
{
    if (!self::ipValidate($ip)) {
        return false;
    }
    $hostname = gethostbyaddr($ip);
    if (!$hostname || $hostname === $ip) {
        return false;
    }
    $forward_ips = gethostbynamel($hostname);
    if (!$forward_ips) {
        return false;
    }
    if (in_array($ip, $forward_ips, true)) {
        return $hostname;
    }
    // FCrDNS verification failed - possible PTR spoofing attempt
    return false;
}
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 →