Four Wordfence-assigned CVEs published to NVD on the morning of September 5, 2026 share one sink: plugin code that rewrites comment HTML after WordPress core’s sanitizer has already cleaned it.
What happened
NVD published four records on September 5, 2026, all assigned by [email protected], all scored CVSS 7.2, all filed under CWE-79, and all carrying the identical vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N. All four are titled some variation of “Stored Cross-Site Scripting via Comment Content.” All four are still marked Received, meaning NVD has not yet enriched them and no CPE configuration exists for any of them.
The four:
- CVE-2026-78438 — W3 Total Cache, all versions up to and including 2.10.5, “via LazyLoad Background Mutator.” The record states it “requires the ‘Lazy Load Images’ feature with ‘Process background images’ to be enabled, and the malicious comment to be approved by a moderator before execution is triggered.” W3 Total Cache reports 900,000+ active installations.
- CVE-2026-77830 — Spam protection, Honeypot, Anti-Spam by CleanTalk, up to and including 6.86, “aria-label Placeholder.” Published at
2026-09-05T07:17:12.163. 200,000+ active installations. - CVE-2026-77263 — iubenda All-in-one Compliance, up to and including 3.13.4. 200,000+ active installations.
- CVE-2026-77233 — iubenda again, same version ceiling, “via AdSense Regex Rewrite.” The record limits it: the flaw “only manifests when the ‘Secondary’ parser engine is active (parser_engine=default); it does not exist under the default ‘new’ DOM-based parser engine.”
The mechanism is stated most plainly in the CVE-2026-77263 record, which is worth quoting in full because it describes the whole class:
“The exploit works by embedding KSES-allowed markup such as abbr title attributes and HTML comments in a submitted comment so that the global strtr() substitution strips substrings from an inert tag, mutating it into an executable element such as an img onerror handler that runs in the WordPress origin for any visitor, including logged-in administrators.”
Read that sequence carefully. The payload enters as markup WordPress’s own KSES filter permits — an abbr tag with a title attribute, and an HTML comment. At the moment the comment is accepted, the string is legal and inert. It becomes an img onerror handler later, because a plugin ran a character substitution over the rendered output and deleted the characters that were holding the tag together.
The other three follow the same shape with different rewriters. W3 Total Cache’s lazy-load mutator walks rendered HTML looking for background images to defer, and the fix in 2.10.6 is described as matching “background styles as top-level attributes only.” CleanTalk’s ContactsEncoder obfuscates contact details in output so scrapers cannot harvest them; the fix skips “encoding inside excluded HTML attributes.” iubenda’s Secondary parser engine rewrites AdSense markup for cookie-consent compliance. The referenced Trac lines are specific enough to inspect: UserExperience_LazyLoad_Mutator.php lines 91, 255 and 293 for W3 Total Cache; ContactsEncoder.php lines 914 and 933 for CleanTalk; iubenda.class.php lines 381, 557, 570 and 941. Each record also links the fixing changeset — 3680101, 3677388 and 3675630 respectively.
Fixes exist and are shipping. W3 Total Cache 2.10.6 was published to the plugin directory about 20 hours before this was written, which puts it on September 4, 2026. CleanTalk 6.87 is dated September 2, 2026 in the vendor’s own changelog. iubenda 3.13.5 was listed as four days old, which puts it on or about September 1, 2026.
None of the three changelogs uses the word “security,” “XSS,” or “cross-site scripting” for the relevant entry.
- iubenda 3.13.5: “Improved: Removed obsolete legacy Google AdSense (show_ads.js) handling from the Secondary parser engine.”
- CleanTalk 6.87: “Fix. ContactEncoder. Skip encoding inside excluded HTML attributes. (#869)” — the release does contain a separate bare line reading “Upd. Code. Security review,” but it is not attached to that entry.
- W3 Total Cache 2.10.6: “Fix: Lazy Load: Match background styles as top-level attributes only” — the twentieth of twenty-two lines, sitting between “Fix: CDN: Scope CORS headers to font resources” and “Fix: Admin: Align request validation across notice, extension, setup, CDN, and minify flows.”
Why it matters
Sanitization is a contract about a moment. WordPress cleans comment content once, at a defined point, against a defined allowlist. Every transform applied to that output afterward is a fresh opportunity to violate the contract, and none of these four transforms was written as a security control. One is a cache optimizer. One is a scraper defense. Two are compliance rewriters. They are all in the business of editing HTML that something else already declared safe, and the declaration does not survive the edit.
That is what makes this class hard to defend with input filtering, which is where most WordPress hardening effort goes. There is no bad input to reject in the iubenda case. <abbr title="..."> is exactly the markup KSES exists to permit. A WAF inspecting the submitted comment sees nothing wrong, because at that point nothing is wrong. The dangerous string is manufactured on the way out, by the site’s own code, from parts that were individually harmless. Any control that runs before the rewriter is looking at the wrong artifact.
Comment content is also the worst possible place for this to happen, because it is the one long attacker-controlled string that a very large share of WordPress sites accept from complete strangers by design. A plugin that rewrites post content processes what the site’s own authors wrote. A plugin that rewrites comment output processes what the internet wrote. Three of these four run on that input on any site with comments open, with no authentication required — PR:N in every vector.
The CleanTalk entry deserves a note of its own, and not only because an anti-spam plugin ended up as the sink in the comment stream it was installed to protect. Its record contradicts itself. One sentence says the flaw “makes it possible for authenticated attackers, with custom-level access and above, to inject arbitrary web scripts.” The next says “the payload is deliverable via unauthenticated comment submission.” The CVSS vector Wordfence assigned to its own record reads PR:N. Two of those three statements say no privileges are required and one says custom-level access is required, in a record that is the authoritative description and that NVD has not enriched. An operator reading only the first sentence would conclude the flaw needs an account. It does not.
Then there is the changelog problem, which this site has now seen enough times to call a pattern rather than an accident. In the TranslatePress case on August 29, the release that reportedly carried a 9.8 fix had no changelog entry at all. Here the entries exist, and are accurate, and are useless for triage. An administrator deciding on September 4 whether to update a cache plugin across a fleet had “Match background styles as top-level attributes only” and twenty-one siblings, with no severity marker and no CVE, because the CVE did not publish until the next day. That ordering is normal and defensible — vendors ship first and disclose after. But it means the changelog is the only signal available during the window when updating actually helps, and in all three of these cases the changelog gave the operator nothing to sort on.
What to do
- W3 Total Cache: update to 2.10.6. If you cannot, the record names its own precondition — the flaw needs “Lazy Load Images” with “Process background images” enabled. Turning off background-image processing removes the sink while you schedule the update.
- CleanTalk: update to 6.87. Do not rely on the record’s “authenticated attackers, with custom-level access and above” sentence when assessing exposure; treat it as unauthenticated, per the vector and the record’s own next sentence.
- iubenda: update to 3.13.5. If you are pinned, CVE-2026-77233 applies only under the Secondary parser engine (
parser_engine=default) and, per the record, not under the default DOM-based engine. CVE-2026-77263 carries no such carve-out — that one applies regardless. - Moderation is a real control here, but only partly. Both the W3 Total Cache and CleanTalk records require an approved comment before execution. The iubenda records state no moderation precondition.
- Audit your own plugin set for the class, not the CVEs. Anything that filters, mutates, minifies, lazy-loads, obfuscates, or regex-rewrites rendered comment output is in scope by construction, whether or not it has a CVE yet.
Sourcing note
All four CVE records were read from NVD’s API (services.nvd.nist.gov/rest/json/cves/2.0); CVE-2026-77830 was retrieved twice, with different query forms, to confirm both the contradictory privilege language and the PR:N vector before reporting the conflict. All four carry vulnStatus of Received, so the CNA prose is currently the whole record. Version numbers, install counts, release dates and changelog text come from each plugin’s page in the WordPress.org plugin directory, read directly.
Wordfence’s own advisory pages were not retrievable from here — the request returned empty content, which is the same obstacle this site logged on August 29 — so the CNA’s descriptions were read through NVD’s republication rather than at the source. The api.wordpress.org plugin-information endpoint and Trac’s log view are disallowed to automated retrieval, so the Trac line and changeset numbers above are reproduced from the CVE records’ reference lists and have not been opened. Relative release ages (“20 hours ago,” “4 days ago”) are as displayed by wordpress.org at the time of reading and are converted to dates here as approximations; CleanTalk’s 6.87 date is the vendor’s own, given as 02.09.2026.
Unresolved: whether the four findings come from one researcher or several. Wordfence credits researchers on its advisory pages, which could not be read. Also unresolved is whether the “Upd. Code. Security review” line in CleanTalk 6.87 refers to this fix or to unrelated work. Neither question changes the mitigation.
