Quick answer: The Polyfill.io supply chain attack began when the widely embedded polyfill.io domain was sold to Funnull in February 2024 and started serving malicious JavaScript by June. cside was first to report the real scale of the attack: more than 490,000 websites, not the 100,000 that nearly every outlet repeated. That lower number was just where the search tool stopped counting. A year later the U.S. Treasury sanctioned Funnull over the operation. This is the full timeline, what the code did, and how to find and remove it.
The Polyfill.io attack is one of the clearest browser supply-chain incidents on record. A free, trusted utility sat on hundreds of thousands of sites for years. New owners turned it into an attack surface overnight. No site owner changed a line of code, yet their visitors were exposed.
This page pulls the whole story into one place: a dated timeline, the truth behind the "100,000 sites" number, what the payload actually did, the CVE, the Funnull sanctions that followed, and a practical cleanup checklist. For deeper dives, each section links to our original reporting from 2024 and 2025.
The short version
- The polyfill.io domain was sold to Funnull in February 2024. By June it was serving malicious redirects.
- There is no incident-wide CVE; the closest, CVE-2024-38526, is scoped to the pdoc documentation tool that loaded polyfill.io — not the attack itself.
- The real scale was 490,000+ websites, not the widely quoted 100,000. That figure was PublicWWW's default result cap. cside reported the true number first.
- The captured payload was a mobile-only redirect to scam and betting sites, built to evade researchers.
- On 2025-05-29, OFAC sanctioned Funnull and its administrator Liu Lizhi.
- As of 2026-05-18, more than 61,000 pages still embed polyfill.io. If yours is one of them, remove it.
Full timeline (2009–2026)
| Date | Event |
|---|---|
| 2009–2010 | Remy Sharp coins the term "polyfill"; the idea spreads through the web development community |
| 2014 | Andrew Betts builds the polyfill.io service at Financial Times Labs; one script tag tailors polyfills to each browser |
| 2014-10-28 | HTML5 becomes a W3C Recommendation; evergreen, auto-updating browsers soon make polyfill.io largely unnecessary |
| ~2023 | The Financial Times hands the project to its long-time maintainer, Jake Champion |
| Feb 2024 | The polyfill.io domain and GitHub repository are sold to Funnull, a Chinese-operated company |
| 2024-02-25 | Andrew Betts warns publicly: "If your website uses polyfill.io, remove it IMMEDIATELY" |
| 2024-02-29 | Cloudflare publishes a safe cdnjs mirror to reduce supply-chain risk; Fastly stands up its own mirror days earlier |
| 2024-06-24 | Japanese researcher "piyokango" flags the malicious behavior |
| 2024-06-25 | Sansec publishes its forensic disclosure; cside publishes the same day and reports the real 490,000+ scale |
| 2024-06-26 | Cloudflare begins auto-rewriting polyfill.io to its mirror; Google warns affected advertisers |
| 2024-06-27 | Namecheap suspends the polyfill.io domain |
| 2024-07-02 | Censys independently counts 384,773 affected hosts |
| 2025-05-29 | OFAC sanctions Funnull and administrator Liu Lizhi; the FBI ties 548 Funnull CNAMEs to 332,000+ domains |
| 2026-05-18 | 61,593 pages still embed polyfill.io |
The "100,000 sites" number was wrong
Almost every report about this attack used the same figure: roughly 100,000 sites. That number is an artifact of the tool, not a measurement of the attack.
Researchers, cside included, used PublicWWW to find every page containing the polyfill.io snippet. PublicWWW caps results at 100,000 by default. So every count that relied on it landed at "100,000+." When we ran the search past the cap, the real number was more than 490,000 websites.
This matters because the affected set was not random. It skewed heavily toward high-traffic, high-trust destinations: banks, government sites, major publishers, and well-known brands. Reporting "100,000" undersold an attack that was nearly five times larger. cside surfacing the true 490,000+ figure is the correction the public record needed, and Censys's independent count of 384,773 hosts on 2024-07-02 confirms the scale was far past 100,000.
What the malicious code actually did
The behavior that was captured, decoded, and published was a redirect. Sansec's forensic report on 2024-06-25 showed the tampered script sending some mobile visitors through a fake Google Analytics typosquat, googie-anaiytics[.]com (note the swapped letters), and on to sports-betting and adult sites.
The tradecraft is what made it dangerous and hard to catch. The redirect:
- fired only on mobile devices, never desktop;
- varied by geographic region and by time of day;
- hit each device or IP only once, so neither a victim nor a researcher could reproduce it on refresh;
- went quiet when it detected an admin user or the presence of web analytics;
- shipped with anti-reverse-engineering armor.
Because polyfill.io was a dynamic service by design, the operator could serve clean code to one visitor and malicious code to the next. Subresource Integrity could not help, because it pins a hash of a fixed file and this service had no fixed file. The script ran first-party in each site's own origin, so it had access to that page's DOM, forms, and cookies, and it sat on the CSP allowlists of hundreds of thousands of trusted domains.
Was it only a redirect? That is the honest, unresolved part. Independent deobfuscation of the recovered payload found redirect logic and nothing else, no keystroke capture, no credential theft. But the per-request design means a variant aimed at one high-value visitor need never appear in any public scan. The redirect is what was caught. What else may have run during those months cannot be proven either way. We made the capability case in detail in The Polyfill.io attack: more than just a redirect attack.
For the full incident write-up from the time, see The Polyfill attack explained and our same-day report, More than 490k websites targeted in a web supply chain attack.
Is there a CVE for the Polyfill.io attack?
There is no single CVE assigned to the Polyfill.io incident itself. The closest identifier in the National Vulnerability Database is CVE-2024-38526, but it is scoped to pdoc — a Python API-documentation tool that linked to polyfill.io in the docs it generated (fixed in pdoc 14.5.1). It does not cover cdn.polyfill[.]io or the wider set of affected sites. If you manage a vulnerability program, track this incident by its affected domains (cdn.polyfill[.]io, plus the related bootcdn[.]net, bootcss[.]com, staticfile[.]net, staticfile[.]org, and unionadjs[.]com) rather than a single CVE, and reference CVE-2024-38526 only for pdoc exposure.
The Funnull connection and the 2025 sanctions
Polyfill.io was not a one-off. The domain's buyer, Funnull, ran a much larger operation.
On 2025-05-29, the U.S. Treasury's Office of Foreign Assets Control sanctioned Funnull Technology Inc. and its administrator, Liu Lizhi. Treasury tied Funnull's infrastructure to more than $200 million in U.S. victim-reported losses from investment scams, the pattern often called pig butchering. Its notice described the polyfill connection without naming the service: in 2024 Funnull "purchased a repository of code used by web developers and maliciously altered the code to redirect visitors of legitimate websites to scam websites and online gambling sites."
The same day, the FBI tied 548 Funnull CNAMEs to more than 332,000 domains. This is infrastructure laundering: renting reputable cloud and CDN space through illicit accounts and reselling it to scammers so malicious sites look legitimate and stay hard to remove. We covered the sanctions and what they mean for security teams in Funnull sanctioned: what the Polyfill.io attack exposed about infrastructure laundering.
Who is still exposed
Sanctions disrupt a company. They do not remove code from your site. As of 2026-05-18, PublicWWW still listed 61,593 pages containing polyfill.io, well over a year after the domain was suspended.
That residue is the real lesson. Browser dependencies stay embedded long after a domain is blocked, because people do not remove things. Every one of those pages is still pointed at a domain that has already been weaponized once.
How to find and remove Polyfill.io today
Start with the pages that touch login, checkout, account creation, payment, and personal data.
- Search your source code, tag managers, CMS templates, and legacy snippets for
polyfill.io, plus the related domainsbootcdn[.]net,bootcss[.]com,staticfile[.]net,staticfile[.]org, andunionadjs[.]com. - Remove the references. Modern browsers no longer need these polyfills, so deletion is safer than swapping in a mirror.
- Map every remaining third-party script to an owner, a purpose, a page scope, and a data-access level.
- Flag scripts that load more scripts, build URLs dynamically, or behave differently by user agent, region, or session.
- Use Subresource Integrity only where a script is static and the provider supports stable hashes.
- Tighten Content Security Policy on sensitive flows, starting in report-only mode.
- Monitor what scripts actually do at runtime, so an ownership change or a new payload is visible when real users load the page.
What this attack teaches about client-side security
The Polyfill.io attack worked because trust was treated as permanent. A script approved once kept running after the company behind it changed and after the code it served changed. Server logs did not see it. Vendor questionnaires did not catch it. The browser executed it anyway.
That gap, between trusted inclusion and runtime execution, is exactly what cside was built to close. cside works at the browser layer, where third-party scripts actually run. It shows which scripts load on real pages, what they call, how they change, and whether they attempt suspicious behavior such as unexpected redirects or data access. In the Polyfill.io case, that runtime view is what flags a trusted dependency the moment it turns hostile.
The next polyfill.io is already on the web somewhere, embedded and trusted. The only reliable way to catch it is to watch what your scripts do, not just who shipped them. Secure your site for free with cside and see every script your users actually load.







