Blog / The polyfill.io Supply-Chain Attack — Every Script Tag Is a Trust Decision
security supply-chain javascript change-detection

The polyfill.io Supply-Chain Attack — Every Script Tag Is a Trust Decision

The polyfill.io CDN is injecting malicious code into 100,000+ sites. What happened, why SRI didn't save anyone, and how to defend against the next one.
The CompleteStatus Team · · 6 min read
The polyfill.io Supply-Chain Attack — Every Script Tag Is a Trust Decision
Want this checked continuously?
CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.
Monitor your site free

If your site has a <script src="https://cdn.polyfill.io/..."> tag anywhere in it, stop reading and go remove it — then come back, because the rest of this matters too. This week the polyfill.io CDN — a service embedded, by some estimates, in over 100,000 websites — was caught injecting malicious code into the JavaScript it serves. It's the textbook supply-chain attack security people have warned about for years: not a breach, not a bug, but a trusted piece of infrastructure changing owners and then changing behavior.

Events are still unfolding as we write this, but the shape of the incident is clear enough to draw lessons from — and they apply to every third-party script tag on every site you run.

What happened

Polyfill.io began life as a genuinely useful open-source service: it read each visitor's User-Agent and served exactly the JavaScript polyfills that browser needed — nothing for modern browsers, compatibility shims for old ones. Convenient, free, and adopted very widely.

Then the supply chain shifted under everyone's feet:

  • February 2024: the polyfill.io domain and the project's GitHub account are sold to a company called Funnull, reportedly China-linked and previously unknown to most of the web community. The original developer publicly warns that no site should keep using the domain, noting he never owned it and that any site embedding it now trusts the new owner completely. Cloudflare and Fastly stand up clean, trustworthy mirrors of the service in response.
  • This week (late June): researchers at Sansec publish evidence that the CDN is now injecting malicious code into the polyfills it serves. The injected payload — observed redirecting visitors to sports-betting and other scam sites — is selective and evasive: it reportedly activates mainly on mobile devices, at certain hours, and avoids firing when analytics tools or admin-looking sessions are detected. That selectivity is the point: the site owner checks their own site, sees nothing, and stays embedded.
  • Right now: the response is escalating day by day. Cloudflare has begun automatically rewriting polyfill.io URLs to its own clean mirror for sites behind its proxy; warnings are propagating through ad platforms and hosting providers; and registrar action against the domain itself is underway. By the time you read this the domain may already be suspended — but the affected script tags are still sitting in hundreds of thousands of pages, waiting to trust whatever answers at that hostname next.

Every script tag is a trust decision

Here's the uncomfortable general lesson. When you write:

<script src="https://cdn.thirdparty.example/widget.js"></script>

you are granting whoever controls that domain — today, and every day in the future — full JavaScript execution in your users' browsers, in your origin's context. They can read what your users type, capture payment fields, redirect visitors, mine cryptocurrency, or do nothing at all for two years and then start. There is no sandbox. The tag doesn't pin the code; it pins a name, and names get sold.

Polyfill.io wasn't compromised in the Hollywood sense. It was bought. Every dependency you load from a third-party domain carries this exact risk: the maintainer retires, the domain lapses, the company is acquired, the project is sold. Magecart-style attacks have exploited this pattern against payment pages for years; polyfill.io is the same play at enormous scale.

Why Subresource Integrity didn't save anyone

The standard defense for third-party scripts is Subresource Integrity — a cryptographic hash in the tag, so the browser refuses any file that doesn't match:

<script src="https://cdn.example.com/lib@2.1.0/lib.min.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

SRI is excellent — for static files. And here's the trap: polyfill.io was structurally incompatible with SRI, because it served different code to every browser by design. Dynamic, User-Agent-tailored responses can't have a single hash. Anyone who tried to add an integrity attribute broke their site; so nobody did; so when the payload changed, no browser objected.

That's the deeper lesson: a third-party service whose response varies per request is a service you cannot pin. You're trusting the operator in real time, forever.

What to do now

For polyfill.io specifically — remove it. Modern evergreen browsers need few or none of the polyfills it served; most sites can delete the tag outright with no fallout, and the truly cautious can point at the Cloudflare or Fastly mirrors instead. But the durable fixes are general:

  • Inventory your third-party scripts. Every page, every tag, every domain. Most teams are surprised by the list — tag managers, A/B tools, widgets a marketer added in 2021. You cannot defend a supply chain you haven't mapped.
  • Self-host what you can. A copy of a library served from your own origin can't be swapped out from under you. You give up the CDN's caching; you gain the guarantee that your code is your code.
  • Use SRI on everything static that must stay third-party — and treat "this service can't support SRI" as the risk signal it is.
  • Set a Content-Security-Policy. A script-src allowlist limits which domains may execute script at all, and it's the safety net when a tag slips past review. It wouldn't have stopped polyfill.io (the domain was allowlisted, then turned) — but it stops the second stage, the payload loading from attacker infrastructure, and it stops unknown domains from ever appearing.
  • Monitor your rendered pages for change. This is the detection layer the polyfill.io victims lacked. The injected code was designed to hide from site owners casually checking their own sites — but it cannot hide from automated monitoring that fetches your pages and diffs what's actually being served: new script tags, changed script contents, unfamiliar external domains. Sites with rendered-page change detection get an alert the day their supply chain turns; everyone else finds out from a researcher's blog post months later.

Watch what your pages actually serve

The polyfill.io incident will get cleaned up — mirrors are live, registrar action is in motion — but the pattern is permanent: trusted third-party code changing hands and then changing behavior, tuned to be invisible to the site owner. Your defense is knowing, continuously and automatically, what your pages are actually delivering to visitors. CompleteStatus's change-detection monitoring fetches your key pages on a schedule and alerts when content changes unexpectedly — new external script domains, injected markup, modified pages — alongside uptime, SSL and security-header monitoring in one place. We covered how injected-content detection catches CMS compromises in our WordPress monitoring guide; the polyfill.io attack is the same lesson one layer down the stack.

Take twenty minutes today: inventory your script tags, remove what you don't need, and put change detection on the pages that matter — before the next quiet domain sale.

Stop checking by hand

CompleteStatus runs these exact checks around the clock — uptime, SSL, DNS, security headers and SPF/DKIM/DMARC — and alerts you the moment something changes. One dashboard, one bill.
Start free Run a free check
Uptime is table stakes. We watch the rest — security headers, email authentication, certs and DNS, with the fix attached.
Start free
Company
© 2026 CompleteStatus. All rights reserved. CompleteStatus — operated in the United States · support@completestatus.com