Cafiyn Pulse
← Startup Signals
6 min readUpdated 2026-09-25Issue 4

Every third-party script tag is a standing grant to run code on your visitors.

A marketing form, a chat widget, an analytics snippet. Each one is permission for someone else's server to execute whatever it sends, on every page it sits on, forever.

ByKarthik KumarCafiyn Innovations
At a glance
Incident date
14 September 2026
Impact window
15:01 to 20:30 UTC, per Brevo
Customer-embedded files
Live from 16:07 UTC, per Brevo
Stated mechanism
A Cloudflare Worker deployed on Brevo's account
Stated root cause
A long-lived full-permission Cloudflare API key in application source code
Lure
A fake human verification page instructing visitors to paste a command

What Brevo says happened

Brevo published a post-mortem on a 14 September incident. In Brevo's words, an attacker used a compromised Brevo Cloudflare API key to deploy a Cloudflare Worker on its account. Brevo says the Worker injected a malicious script into pages of brevo.com and sibforms.com, and into three JavaScript files that customers embed on their own websites.

The script showed selected visitors a full-screen Cloudflare-branded page, sometimes appearing right after a genuine Cloudflare checkbox, asking them to press Win+R, then Ctrl+V, then Enter. That is a technique known as ClickFix: rather than exploiting the browser, it persuades the person to run the command themselves. Brevo says the pasted command downloaded malware onto the visitor's Windows computer, and that on WordPress sites it attempted to silently install and activate a plugin.

Brevo gives the impact window as 15:01 to 20:30 UTC, with the lure live on the listed customer URLs from 16:07. It states that its application at app.brevo.com was not affected, and that no Brevo systems were modified at their source, the content being altered in transit at its CDN edge. The stated root cause is a long-lived Cloudflare API key with full account permissions stored in application source code.

What Brevo asks affected sites to do

Brevo's own guidance is specific, and worth following if its scripts are on your pages.

  • If you or a visitor ran the pasted command, treat that computer as compromised: disconnect it, run a full antivirus scan, and change passwords
  • If your WordPress site loads Brevo scripts and an administrator visited it while logged in on 14 September, check for any plugin installed or activated that day
  • If you logged in to Brevo via brevo.com on 14 September, change your password and review your API keys

The part that is not about Brevo

Two lessons here generalise, and neither depends on which vendor it happened to.

The first is the root cause. A long-lived API key with full account permissions, stored in source code, is a configuration most teams have somewhere. CDN tokens, DNS tokens, registrar API keys, object storage keys. They are created once during setup, given broad permissions because scoping them is fiddly, committed to make a deploy script work, and then never touched again. The right response is not to feel superior about it but to go looking for your own.

The second is the embed. When you put a third-party script tag on your page, you are granting that vendor's infrastructure permission to execute arbitrary code in your users' browsers, on every page that carries the tag, for as long as it is there. The content of that script can change at any time without any action from you, which is exactly why the tag is convenient. Your security posture on those pages is the union of yours and theirs.

Auditing your own embeds

Most teams have more third-party scripts than they remember adding, because they accumulate one marketing request at a time. Start by counting them, then decide what each one is worth.

  • List every third-party script on your site, including tags injected by a tag manager, which is itself a script that can add more
  • For each one, ask what it would mean if that vendor served different code tomorrow. If the answer is serious, that page should not carry it
  • Keep third-party scripts off pages that handle authentication, payment or account settings, where the consequence of injected code is highest
  • Use Subresource Integrity where the vendor serves a versioned, immutable file. Note that it does not help for loader scripts designed to change, which is most analytics and chat widgets
  • Set a Content Security Policy that lists allowed script origins, so a script injected from an unexpected origin is blocked even if a tag is tampered with
  • Prefer a server-side integration over a browser embed where the vendor offers one

And your own keys

The root cause deserves an hour of your week regardless of which vendors you use. Find the long-lived, broadly-scoped credentials in your own systems and narrow them.

  • Search repositories and their history for CDN, DNS, registrar and object storage API keys
  • Replace full-account tokens with tokens scoped to a single zone, bucket or permission
  • Move anything remaining into a secret manager rather than source code, and rotate it as you move it
  • Turn on alerting for configuration changes at your CDN and DNS provider, since that is where an injection like this becomes visible first

What to do

  1. 1Follow Brevo's guidance if its scripts are on your pages, including the WordPress plugin check for 14 September.
  2. 2Inventory every third-party script on your site and remove the ones nobody can justify.
  3. 3Keep third-party embeds off authentication, payment and account settings pages.
  4. 4Set a Content Security Policy listing allowed script origins.
  5. 5Find and rescope long-lived full-permission CDN and DNS API keys in your own repositories.

Common questions

What is ClickFix?

A social engineering technique where a page shows a fake verification or error prompt and instructs the visitor to copy a command and run it themselves, typically via the Windows Run dialog. It sidesteps browser security because the person executes the command, not the page.

What does Brevo say was affected?

Brevo says the Worker injected a script into pages of brevo.com and sibforms.com and into three JavaScript files that customers embed on their own sites. It states that its application at app.brevo.com was not affected, and that no Brevo systems were modified at their source.

Does Subresource Integrity solve this?

Only partly. SRI verifies a file against a hash you pin, which works for versioned immutable assets. It does not work for loader scripts that are designed to change, which is how most analytics and chat widgets are delivered.

What is the safest place to start?

Remove third-party scripts from pages that handle authentication, payment or account settings. That is where injected code does the most damage, and it is usually the easiest change to justify internally.

Why does a full-permission API key matter so much?

Because the blast radius is the whole account rather than one resource. In Brevo's stated root cause, a full-permission Cloudflare key stored in source code was enough to deploy a Worker that altered content in transit for every site loading the affected files.

Sources

Read against the primary documentation rather than secondary coverage. Where a figure comes from a provider's own docs, it is quoted as published on 2026-09-25.

Related

More from Signals

A 9.5 in next/og. Whether it reaches you depends on one line in your OG route.
The advisory rates it 9.5, but it only fires if your OG image route puts attacker-controlled text into SVG. Here is how to find out which side of that line you are on.
OpenAI and Anthropic both cut prices on 22 September. One of them costs you a refactor.
Two frontier price cuts in one day is a good week for anyone paying a token bill. The migration cost is not evenly distributed, and one of the two prices comes with an expiry hedge.
A package install reads your home directory. This week two of them did it on purpose.
The implant did nothing clever. It read the files your shell reads, in the place your credentials live, and sent them somewhere else. That is the whole attack, and it works.
GitHub is switching off SHA-1 SSH keys. Find out now whether yours is one of them.
The keys at risk are the old ones, on the machines nobody logs into, in the pipelines that have run untouched for three years. Those are also the ones that will fail loudest.
1.8 million Android apps were scanned for hardcoded keys. Here is how to check yours.
Finding secrets in shipped apps is now a cheap, automated pipeline. Anything compiled into an APK, an IPA or a JavaScript bundle should be treated as already published.
OpenAI's Agents API will hold your agent state. What breaks if you ever need to leave.
Two major providers moved into the agent state layer in the same week. A managed harness is a real shortcut, as long as you keep a copy of what it holds.
Meta's Muse agent can now check out at your store. What merchants should change.
Agent purchases are arriving through wallets and single-use cards, not through merchants adopting a new protocol. Many merchants will receive them without choosing to.
What Brevo's SSO incident teaches about multi-tenant SAML and hijacked sending accounts.
One incident, two lessons: why email authentication did not help, and the tenant-scoping mistake anyone shipping SSO can make.
Cloudflare now sorts bots into Search, Training and Agent. What it means for your site and your agent.
The same change lands on two audiences. Site owners can now accidentally block search; agent builders will find more doors closed.
OpenAI has published seven shutdown dates. Here is the calendar.
Seven dates between 23 October and 26 February. Every one announced months ahead, in public. The failure mode is never the notice.
Nvidia bought Hugging Face. Your open-weight fallback is now a vendor relationship.
The commitments say nothing breaks. The structural change is that "we can always self-host" is now a dependency on one vendor rather than on a neutral commons.
The Videos API goes away on 24 September and OpenAI names nothing to move to.
Every other deprecation on OpenAI's page offers a migration target. This one does not, which makes it a different kind of problem.
Whisper shuts down on 26 February. The risk is not the deadline.
Five months is a generous window. Whisper is also typically wired into a background job that fails into a queue rather than into a user's face.
The Assistants API is gone. Your app may not have told you yet.
It shut down on 26 August 2026. The replacement is not a drop-in, and the most common migration mistake changes your model's behaviour without throwing an error.
One Copilot code review costs 13 requests. Here is the rest of the maths.
Copilot now bills on usage rather than seats. The headline change is simple. The multipliers underneath it are where teams get surprised.
Row-level security is on by default now. That is not the same as being protected.
Lovable fixed the default. The gap that actually leaks data was never the default, it was the policy, and no platform can write that for you.
Your model comparison is measuring the wrong number.
Every price list is per token. Your bill is per finished piece of work. Those two numbers can rank models in opposite orders.
An agent with production log access is a new identity. Treat it like one.
Always-on agents that read production logs are arriving fast. The access-control question they raise is old and well understood, which is the good news.

Open the tool.

Ten production categories, three minutes, and a ranked list of what to fix first.

Check your own stack