Brevo Breach: Stolen Cloudflare Key Pushed ClickFix and a WordPress Backdoor to 100K Sites
A hardcoded Cloudflare API key let an attacker deploy an edge Worker that rewrote Brevo's embedded scripts for five hours, serving ClickFix lures and a hidden WordPress backdoor to 100,000+ sites.
For roughly five and a half hours on 14 September 2026, the JavaScript that Brevo's customers embed for forms, chat and tracking arrived at browsers with an extra payload attached. Nobody touched Brevo's servers. An attacker holding a long-lived Cloudflare API key deployed a Worker at the CDN edge that rewrote responses in flight, stripped the Content-Security-Policy header, and appended a loader to three of the company's embedded scripts. Sansec estimates more than 100,000 websites served the result. It was Brevo's second security incident in five days.
What Happened
Brevo's post-mortem, published on its status page the same evening, gives a tight timeline (all UTC, 14 September):
- **14:23** — the attacker created a hostname on a Brevo-owned domain.
- **14:28** — a malicious Cloudflare Worker was deployed and tested against low-traffic domains.
- **14:42** — the Worker was routed to brevo.com.
- **15:01** — full impact began across brevo.com.
- **16:07** — the Worker was updated to append a loader to three embedded JavaScript files and routed to sibforms.com.
- **19:33** — Brevo opened a security incident.
- **20:30** — the Worker was removed and the compromised key revoked; injection stopped.
- **20:42** — independent verification confirmed affected pages were clean.
Brevo puts the impact window at 15:01 to 20:30, or 5 hours 29 minutes. Sansec, whose CSP monitoring caught the injection on customer sites, measures the window for the embedded files at 16:05 to 20:12. The two figures are consistent: Brevo's own pages were hit first, and the customer-facing scripts only from 16:07.
The root cause is unambiguous in Brevo's own words. A Cloudflare API key with "full account permissions" was "stored in application source code." The company's investigation found the key was "first misused in late August 2026," though it says no malicious content reached customer-facing pages before 14 September. Sansec independently noted that a TLS certificate for the attacker's first hostname, `cdn.sendibt1.com`, was issued on 25 August, three weeks before the injection went live.
Who Is Affected
Three groups, with very different exposure.
**Brevo's own properties.** brevo.com, sendinblue.com, the login, account, onboarding and "my" subdomains, and sibforms.com all served the injected script. Brevo says app.brevo.com, the API, email sending and customer account data were not affected.
**Every site embedding the modified scripts.** Sansec identified three altered assets: the SDK loader at `cdn.brevo.com/js/sdk-loader.js`, the Conversations chat widget at `conversations-widget.brevo.com/brevo-conversations.js`, and Brevo's hosted forms script. Anyone who loaded a Brevo form, chat bubble or tracker between 16:07 and 20:30 UTC pulled the loader too. Sansec's estimate of "more than 100 thousand" sites comes from a PublicWWW search for pages referencing brevo.com, sibforms.com or sibautomation.com; its own CSP monitor logged 2,549 violation reports across 12 customer sites during the window. Brevo's phrasing is "up to 100,000 websites."
**Visitors to those sites.** The script was selective. Brevo says "most visitors and repeat visits saw nothing," and Sansec found it did not activate for crawlers, developers or automated scanners, gating execution behind fingerprinting and proof-of-work endpoints on the attacker's hostnames. The people who did see it got one of two payloads, described below.
Technical Analysis
The delivery mechanism is the interesting part. A Cloudflare Worker attached to a route runs before the origin, and it can modify any response passing through. Brevo's write-up spells out the consequence: "Because the Worker rewrote responses at the edge and removed security headers such as Content-Security-Policy, our origin servers remained unmodified." Every integrity check pointed at the origin passed, because the origin was fine. Sansec observed the same thing from outside: the modified files kept identical Last-Modified dates before, during and after the incident.
The injection itself was minimal. Sansec recovered the appended snippet, which creates a script element pointing at `cdn2.sendibt1.com/f.js` and drops it into the document head. The domain matters: `sendibt1.com` is Brevo's legitimate email-tracking domain, and the attacker used the stolen key to create `cdn`, `cdn2`, `cdn3`, `cdn4`, `cdn9`, `cdn10` and `cdn11` subdomains under it, all proxied through Cloudflare. Sansec warns explicitly against blocking the apex, which would break legitimate link tracking. All of the attacker hostnames stopped resolving on 15 September.
The loader branched on who was visiting.
For ordinary visitors on Windows, it drew a full-page "Cloudflare, verify you are human" overlay, placed a command on the clipboard, and instructed them to press Win+R, Ctrl+V and Enter. Brevo states plainly that this "downloaded malware onto the visitor's Windows computer." It is the paste-and-run pattern covered in "How ClickFix Attacks Turn a Fake CAPTCHA Into Remote Code Execution," delivered this time through a trusted vendor's script tag rather than malvertising or individually compromised sites. Neither Brevo nor Sansec has named the Windows payload.
For visitors logged into WordPress as an administrator, the script skipped the lure and went straight for persistence. Sansec's telemetry shows it fetching a ZIP from `cdn10.sendibt1.com/p/wm.zip`, submitting it with a POST to `/wp-admin/update.php?action=upload-plugin`, then activating it with a GET to `/wp-admin/plugins.php?action=activate`. Sansec could not retrieve the archive; BleepingComputer later found it on VirusTotal. The plugin calls itself "Web Media Optimizer." It copies itself into the must-use plugins directory, hides from the plugin list, beacons to `glegchner[.]com/ads.php`, and carries a hardcoded authentication key that lets the operator mint a valid administrator session without a password. That is a full site takeover that survives a normal plugin audit. The mechanics of that hunt are the subject of "How to Find a Hidden WordPress Plugin Backdoor After a Supply-Chain Injection."
The attacker did not need a vulnerabilityVulnerability🛡️A weakness in software, hardware, or processes that can be exploited by attackers to gain unauthorized access or cause harm. in Brevo's software, only one credential that could create Workers, routes and DNS records across every zone in the account. Why an embedded script grants its vendor that much reach is the point of "Why a Third-Party Script Tag Hands Its Vendor Control of Every Page It Loads On," and why the credential class deserves special handling is the argument in "Why a Long-Lived CDN API Key Is the Most Dangerous Secret in Your Codebase."
The Incident Four Days Earlier
On 10 September at 06:30 UTC, Brevo identified a separate breach: an attacker had exploited a flaw in its SAML SSO implementation to reach 138 customer accounts. The technique, per Brevo's write-up, was to create a Brevo account, enable SSO on it, invite legitimate Brevo users into that SSO configuration, and authenticate them through an identity provider the attacker controlled. Brevo's system then "wrongly granted the attacker access to all organizations those users could reach" instead of confining the session to the organization that owned the SSO configuration. Six of the accounts were used to send phishingPhishing🛡️A social engineering attack using fake emails or websites to steal login credentials or personal info., 43 had their contact lists exported, and 93 showed no meaningful activity. The route was closed at 08:30 UTC and every session on the platform was terminated.
The highest-profile victim was hardware-wallet maker Trezor, which told customers the attacker had sent phishing messages to 347,000 addresses stored in its Brevo account under the subject "Critical Security Alert: STM32 Entropy Vulnerability," directing recipients to a site that asked for wallet backup phrases. Trezor said roughly 2,500 people clicked before the link was taken offline. BitBox and CoinTracking reported similar abuse. Brevo's own advice captured the problem: the messages "were sent through legitimate infrastructure, so they passed the usual email authentication checks."
Brevo has not publicly connected the two incidents. The Cloudflare key was first misused in late August, before the SSO flaw was exploited, which suggests separate access paths even if the same actor was behind both.
Immediate Actions
Prioritise by which of the three affected groups you fall into.
**If you run WordPress with any Brevo embed**, assume an administrator may have loaded a page during the window. Search the access log for a POST to `/wp-admin/update.php?action=upload-plugin` on 14 September and a GET to `/wp-admin/plugins.php?action=activate` shortly after. List plugins installed or activated that day. Compare the plugin directory on disk, including `wp-content/mu-plugins`, against what the admin screen shows. If anything is out of place, remove it, rotate every administrator password, and check for administrator accounts you did not create.
**If you embed Brevo scripts on any platform**, review what those pages did between 16:05 and 20:30 UTC on 14 September. Brevo says the Conversations widget, SDK and forms "are safe to use" and "were never modified at their source," so there is nothing to update, but a CSP report log from that window will tell you whether your visitors were served the loader.
**If any user ran the pasted command**, Brevo's guidance is the correct one: treat the machine as compromised, disconnect it, run a full antivirus scan and change every password used on it.
**If you logged into Brevo via brevo.com on 14 September**, change your Brevo password and review your Brevo API keys.
**If you use Cloudflare**, audit your own account. The audit log records account-level actions and zone changes for 18 months, but there is no built-in notification for Worker deployments, route changes or API token creation; that alert has to be built from the audit log or Logpush.
Long-Term Outlook
Brevo's hardening list is a reasonable template for any SaaS vendor sitting in its customers' page load: hardcoded credentials replaced with narrowly scoped, short-lived tokens; secrets moved into HashiCorp Vault with automatic rotation; alerts on any Cloudflare event that modifies Workers, routes, DNS or account access; Cloudflare logs streamed into security monitoring; integrity protection for versioned embedded assets; and regular external scanning of public pages. Most of that should have existed before a key with full account permissions spent three weeks in an attacker's hands.
For customers, a script tag is an open-ended grant of execution on every page it appears on, and the vendor's edge configuration is now part of your attack surfaceAttack Surface🛡️The sum of all points where an unauthorized user could attempt to enter or extract data from a system: exposed services, interfaces, accounts, and integrations. Reducing attack surface means removing reachability, not just patching.. Subresource Integrity would have blocked the modified files outright, at the cost of breaking on every Brevo update, which is why almost nobody applies it to vendor loaders. CSP reporting cannot stop a script from an allowed origin, but as Sansec's telemetry shows, it is how you learn within minutes that something changed. That detection gap, on both sides, is what turned a five-hour Worker into a six-figure supply-chain event.
Sources
- Brevo status page, "Security Incident - ClickFix" write-up (14 September 2026): https://status.brevo.com/incidents/01M2QBC4EZ24ZACW6SWQYVW8N3/write-up
- Brevo status page, "Attacker gained access to client accounts" write-up (10 September 2026): https://status.brevo.com/incidents/01M266V1CZKJQNGZRNEGFD5CQE/write-up
- Sansec, "Brevo supply chain attackSupply Chain Attack📖A cyberattack that targets an organization by compromising a third-party vendor, supplier, or partner that has access to the target's systems or data. hits 100k+ sites with WordPress backdoors and ClickFix malware" (16 September 2026): https://sansec.io/research/brevo-supply-chain-attack
- BleepingComputer, "Brevo supply-chain attack injected ClickFix scripts on customer sites" (17 September 2026): https://www.bleepingcomputer.com/news/security/brevo-supply-chain-attack-injected-clickfix-scripts-on-customer-sites/
- SecurityWeek, "Brevo Supply Chain Attack Injects Malware Into 100,000 Websites" (18 September 2026): https://www.securityweek.com/brevo-supply-chain-attack-injects-malware-into-100000-websites/
- SecurityWeek, "Trezor Says 347,000 Users Received Phishing Emails After Brevo Hack" (11 September 2026): https://www.securityweek.com/trezor-says-347000-users-received-phishing-emails-after-brevo-hack/
- Cloudflare Docs, Workers routes: https://developers.cloudflare.com/workers/configuration/routing/routes/
- Cloudflare Docs, audit logs: https://developers.cloudflare.com/fundamentals/account/account-security/review-audit-logs/
- Cloudflare Docs, available notifications: https://developers.cloudflare.com/notifications/notification-available/