Illustration of a server pushing tampered scripts through a cloud to many websites, with an exposed key in source code
Part of an ongoing story: Software Supply-Chain Attacks in 2026 →

Brevo supply-chain attack: a hardcoded Cloudflare key at the edge


On September 14, 2026, an attacker used a Cloudflare API key belonging to Brevo, the email marketing platform formerly called Sendinblue, to run a malicious Cloudflare Worker in front of Brevo’s own sites. For several hours the Worker added a script to brevo.com, sibforms.com and three JavaScript files that customers embed on their websites. The script showed some visitors a fake “verify you are human” page (a ClickFix lure) and tried to plant a backdoor plugin on WordPress sites. Security firm Sansec estimates more than 100,000 customer sites loaded the affected files. Four days earlier, on September 10, Brevo had disclosed a separate SAML single sign-on flaw that gave an attacker access to 138 customer accounts.

TL;DR

  • Root cause (per Brevo): a long-lived Cloudflare API key with full account rights sat in application source code.
  • Two payloads: a ClickFix overlay for ordinary visitors, and a fake WordPress plugin (named “Web Media Optimizer,” per BleepingComputer) for logged-in admins.
  • Why checks missed it: the edits happened at the CDN edge, so Brevo’s origin files stayed clean.

What happened

Brevo says the attacker created a hostname on a Brevo-owned domain at 14:23 UTC on September 14, deployed the Worker five minutes later, and routed it to all of brevo.com at 15:01. At 16:07 the Worker began appending a loader line to three embedded files (the forms script, the Brevo Conversations chat widget and the Brevo SDK loader) and was extended to sibforms.com, which hosts signup and unsubscribe forms. Brevo removed it at 20:30.

Sansec confirmed the injected script on www.brevo.com, meet.brevo.com booking pages, the chat widget’s iframe page and sibforms.com. Every loader pointed to a subdomain of sendibt1.com, a Brevo-owned tracking domain where the attacker had added records. Sansec found a certificate for cdn.sendibt1.com dated August 25, consistent with Brevo’s finding that the key was first misused in late August. Brevo says it found no injected content on customer-facing pages before September 14.

How long were sites exposed?

The sources measure different things:

  • Brevo, whole incident: 15:01 to 20:30 UTC, listed as 5 hours 29 minutes. Brevo’s summary calls it “about five and a half hours,” a figure BleepingComputer and SecurityWeek repeat.
  • Brevo, ClickFix active: 16:07 to 20:30 UTC (about 4 hours 23 minutes) on brevo.com, sendinblue.com, Brevo login pages, sibforms.com and the three embedded scripts.
  • Sansec, observed malware: 16:05:18 to 20:12:53 UTC, about four hours, the figure SecurityWeek cites.

Caching stretched the tail. Sansec logged its last report from a cached copy at 17:45 UTC on September 15, about 21 hours after the window closed.

Timeline for Sept 14, 2026 UTC: Worker deployed 14:28, all of brevo.com 15:01, first loader seen 16:05, ClickFix active 16:07, incident opened 19:33, last activity 20:13, key revoked 20:30.
About six hours passed between the Worker going live and Brevo revoking the key. Source: Brevo post-mortem; Sansec analysis (Sept 16, 2026).

Timeline

Date (UTC)EventSource
Aug 25, 17:08Certificate issued for cdn.sendibt1.comSansec
Late AugCloudflare API key first misusedBrevo post-mortem
Sep 10, 06:30SAML SSO flaw identified; 138 accounts accessedBrevo SSO write-up
Sep 10, 08:30SSO route closed, all users signed outBrevo SSO write-up
Sep 14, 14:28Malicious Worker deployedBrevo post-mortem
Sep 14, 15:01Worker covers all of brevo.comBrevo post-mortem
Sep 14, 16:05First malicious sdk-loader.js seenSansec
Sep 14, 16:07Loader added to embedded files; sibforms.com routedBrevo post-mortem
Sep 14, 19:33Incident openedBrevo post-mortem
Sep 14, 20:13Last malware activity seenSansec
Sep 14, 20:30Worker removed, key revokedBrevo post-mortem
Sep 15Malicious hosts stop resolving; customer notices beginSansec; Brevo
Sep 16Sansec analysis publishedSansec
Sep 17BleepingComputer reports Brevo’s post-mortem as “published today”BleepingComputer

The two payloads

Sansec found that the loaded file, f.js, had two branches, both hidden from crawlers, developers and automated scanners.

Flow diagram: a hardcoded Cloudflare key let an attacker run a Worker that injected a loader into Brevo scripts, showing ClickFix to visitors and targeting WordPress admins.
The attack changed what Brevo served, not what Brevo stored, which is why file integrity checks stayed green. Source: Brevo post-mortem; Sansec; BleepingComputer (plugin details).

ClickFix overlay. Brevo says the lure appeared selectively. Targeted visitors got a full-screen page styled as a Cloudflare check, telling them to press Win+R, paste with Ctrl+V and hit Enter. That ran a command the script had already placed on the clipboard, which downloaded malware onto Windows machines. Sansec notes it also reached people who clicked an unsubscribe link in a Brevo campaign email.

Fake WordPress plugin. If the visitor was logged in to WordPress as an admin, the script tried to use that session to upload and activate a plugin from cdn10.sendibt1.com. Sansec could not recover the archive. BleepingComputer found it on VirusTotal and reported that it poses as “Web Media Optimizer,” hides from the plugin list, copies itself into the must-use plugins folder, fetches JavaScript to inject into pages, and holds a hardcoded key that can create an admin session without a password.

Why integrity checks missed it

Brevo says the Worker rewrote responses in transit and stripped headers such as Content-Security-Policy, so the origin stayed untouched and “standard integrity checks did not detect the change.” Sansec had pointed the same way before Brevo confirmed it: the modified files on cdn.brevo.com kept the same Last-Modified dates throughout, and all five Brevo apex domains used Cloudflare DNS, which suggested a single Cloudflare account.

A hash check compares the file on disk with a known-good copy, and an edge Worker never touches that file. A check that fetches the page from outside, the way a visitor does, would see the extra loader line, though Sansec notes the payload itself hid from automated scanners. Sansec’s own evidence came from that side: its Content-Security-Policy monitor recorded 2,549 violation reports across 12 sites.

Four cards: more than 100,000 sites affected per Sansec, a 5 hour 29 minute incident per Brevo, 2,549 CSP violation reports across 12 sites, and a cached copy seen about 21 hours later.
Outside-in monitoring, not file hashes, produced the evidence. Source: Brevo post-mortem; Sansec analysis (Sept 16, 2026).

Brevo’s fix: short-lived, scoped tokens

Brevo says it removed the hardcoded credential and replaced it with narrowly scoped, short-lived tokens. It is moving all Cloudflare keys into HashiCorp Vault with automatic rotation, and is adding alerts that fire whenever Cloudflare’s audit log shows a change to Workers, routes, DNS or who can access the account. It also plans integrity protection for versioned embedded assets and regular external scans of its public pages and scripts.

Brevo has not said how the key was obtained or whether the September 10 SSO incident is connected. SecurityWeek and SecurityAffairs describe the attackers as returning four days later, but BleepingComputer reports that Brevo did not answer that question.

A practical checklist

For developers and platform teams

  1. Replace account-wide, non-expiring API keys with tokens limited to the zones and permissions a job needs, with an expiry date.
  2. Run secret scanning on repositories and CI logs, and block commits that contain credentials.
  3. Alert on edge changes. A new Worker, route, DNS record or account member should page a human.
  4. Watch what you serve, not just what you store: fetch public pages and scripts from outside and compare hashes and headers.
  5. Use Subresource Integrity for pinned third-party scripts, plus a CSP with violation reporting.

For WordPress site owners who embed Brevo code

  1. Search access logs for a POST to /wp-admin/update.php?action=upload-plugin on September 14, followed shortly by a GET to /wp-admin/plugins.php?action=activate (Sansec).
  2. Compare wp-content/plugins/ and wp-content/mu-plugins/ on disk with the admin screen, since the backdoor hides itself.
  3. Remove anything installed that day before rotating admin passwords, because a leftover key can mint sessions. Rotating the WordPress auth salts and checking for unknown admin users also helps.
  4. Anyone who ran the pasted command should treat that computer as compromised, as Brevo advises.
  5. Do not block the sendibt1.com apex domain; Sansec notes it is Brevo’s real email tracking domain.

For Brevo account holders

  • Anyone who signed in to Brevo via brevo.com on September 14 should change their password and review their API keys as a precaution, as Brevo advises.

Background

A software supply-chain attack reaches many targets through one trusted provider. The Axios npm compromise and the LiteLLM PyPI incident changed package code. In Brevo’s case the origin code never changed; the delivery layer did. Related cases are on our 2026 supply-chain attacks story page and in Tech & Security.

What could go right / What could go wrong

What could go right: Scoped tokens, vault storage and audit-log alerts would limit a leaked key and make a rogue Worker visible quickly. Brevo’s detailed timeline helps customers check their own logs.

What could go wrong: Admins who changed passwords but left a must-use plugin behind may still be exposed. Neither Brevo nor Sansec has said how many visitors ran the ClickFix command.

FAQ

Q What happened in the Brevo supply-chain attack?

A On September 14, 2026, an attacker used a Brevo Cloudflare API key to run a Worker that injected a malicious script into brevo.com, sibforms.com and three embedded Brevo scripts. Sansec estimates more than 100,000 customer sites were affected.

Q How long did the Brevo malicious script run?

A Brevo gives 15:01 to 20:30 UTC (about 5.5 hours) for the whole incident, and says the ClickFix lure itself was active from 16:07. Sansec observed malware from 16:05 to 20:13 UTC, about four hours.

Q What is the Web Media Optimizer plugin?

A BleepingComputer reports it is a fake WordPress backdoor plugin installed through logged-in admins' sessions. It hides from the plugin list and persists in the must-use plugins folder.

Q Is the Brevo SSO breach linked to the Cloudflare attack?

A Brevo has not said. BleepingComputer reports that Brevo did not answer whether the two incidents are connected.

Sources

  1. Post-mortem: malicious ClickFix script served via Brevo's Cloudflare account — Brevo Status (primary source)
  2. Incident: Malicious script served via Brevo's Cloudflare account (status updates) — Brevo Status (primary source) ,
  3. Write-up: Attacker gained access to client accounts (SAML SSO incident) — Brevo Status (primary source) ,
  4. Brevo supply chain attack hits 100k+ sites with Wordpress backdoors and Clickfix malware — Sansec (primary source) ,
  5. Brevo supply-chain attack injected ClickFix scripts on customer sites — BleepingComputer ,
  6. Brevo Supply Chain Attack Injects Malware Into 100,000 Websites — SecurityWeek ,
  7. Brevo Supply-Chain Attack Infected Over 100,000 Websites — SecurityAffairs ,