Internet security research and reporting
Analysis Retrospective · 2024

Polyfill.io and the power delegated by a script tag

A third-party script can change a trusted page. The polyfill.io case makes that delegation explicit.

Polyfill.io and the power delegated by a script tag. Website includes script; External delivery service; Page execution context; Visitor interaction
FISRO diagram: Website includes script; External delivery service; Page execution context; Visitor interaction. FISRO

Summary

Sansec’s June 2024 findings and Cloudflare’s response described malicious JavaScript delivery through polyfill.io. This analysis examines executable third-party dependencies, conditional delivery and the limits of script allowlists.

The script ran with the page's privileges

On 25 June 2024, Sansec published findings about malicious JavaScript delivered through the polyfill.io service. Its analysis described conditional behaviour and redirection affecting visitors to sites that embedded the script. Cloudflare subsequently reported corroborating observations and introduced rewriting to its own mirror for proxied sites.

The central trust decision was made by the embedding website. Loading executable JavaScript from another origin lets that code run in the page's context. The visitor did not need to choose the third party independently; the website had already delegated that choice through its script tag.

A library's legitimate purpose does not reduce the privileges of the JavaScript used to deliver it. Compatibility helpers, analytics and support widgets should therefore be reviewed as executable dependencies, rather than treated as decorative page assets.

Read the tag as a delegation statement

This benign example illustrates the difference between serving a reviewed local artefact and requesting live executable content from an external service:

<script src="/assets/reviewed-compatibility-bundle.js" defer></script>

The local path does not make a script safe automatically. It makes the artefact part of the site's own release process, where a team can review and pin what it serves. An external URL may instead delegate future changes to whoever controls the service, domain and delivery system.

For each externally loaded script, record its owner, reason for inclusion, update model and accessible page context. A payment page and a public article may have different exposure consequences even when both load the same third party. The decision should be tied to the page's actual function.

Why one clean fetch is weak evidence

Sansec described conditions affecting when the malicious behaviour appeared, including device and timing checks. A single request from an administrator's browser was therefore an incomplete test of what visitors could receive.

The same limitation applies to incident cleanup. Inspect rendered pages, shared templates, tag-manager configuration and cached assets across the relevant site variants. Searching only the current application repository can miss a script introduced by an older theme, a plugin or a separate publishing system.

Use the organisation's own deployment and browser-observation evidence to establish what was served. Do not visit known malicious destinations with production accounts or treat a broad third-party estimate of affected sites as a measurement of local visitor impact.

CSP and integrity solve different parts of the problem

A Content Security Policy can constrain which script sources are allowed. An allowed source can still serve unwanted code. Subresource Integrity can bind a script to specific content, but it depends on using a stable artefact and an expected digest; a service intentionally returning different content to different clients complicates that model.

The design review should ask which control matches the delivery mechanism. A static, reviewed bundle has different change requirements from a live third-party service. Adding a trusted domain to a long allowlist without an owner turns a policy decision into permanent delegated access.

These are architectural considerations, not claims that any one setting would have prevented every version of the polyfill incident. The actual deployed policy and script delivery path determine the result.

Remove unused authority

Search the delivery material, not just the source branch

In a local checkout and the generated output the team is authorised to inspect, this search locates literal references without contacting the remote service:

rg -n --glob '*.html' --glob '*.js' --glob '*.php' \
  --glob '*.twig' --glob '*.vue' --glob '*.tsx' \
  'polyfill[.]io' .

Run the search separately over the actual deployed output if it differs from the checkout. The example does not inspect a remote site's content, a tag-manager database or HTML created dynamically from another publishing system. Those require their own authorised inventory.

A literal search also misses aliases, encoded URLs and scripts that load another script at runtime. Use it as a starting inventory, then compare the relevant rendered pages and observed browser requests. Record which site variants and caches were covered.

For a stable local JavaScript artefact, the following calculates a SHA-384 digest suitable for preparing an integrity value:

openssl dgst -sha384 -binary reviewed-compatibility-bundle.js |
  openssl base64 -A

The command only computes a digest. It does not verify that the file was reviewed or benign. An integrity attribute must use the digest of the exact served bytes and be tested against the intended loading and cross-origin configuration.

Make removal a release decision

Record the pages changed, the supported-client functionality tested and the deployment identity. Verify that cached or alternate templates no longer restore the old external reference. If a tag-management system can reintroduce it independently, that publishing route needs an owner and a change record too.

The strongest outcome may be eliminating an unnecessary executable dependency. Where the dependency remains necessary, its owner should be able to explain who can change it, how that change is reviewed and how the site could remove it during an incident.

Before replacing a compatibility dependency, establish which supported clients still require its behaviour. An unused script can be removed rather than moved to another external host. Where a replacement is needed, test the required functionality and bring its update path into the normal release review.

3CX shows trusted distribution carrying malicious desktop code; polyfill.io shows the same delegation question inside web pages. libwebp concerns a decoder flaw rather than malicious delivery. Together they give a concrete browser-security checklist: identify the code source, the artefact that ran, the input it processed and the authority available in its execution context.

For the site owner, the outcome to preserve is an inventory of executable third parties with accountable owners and removal criteria. A page should not retain another party's ability to change its behaviour simply because a template copied the tag years earlier.

Timeline

  1. Sansec publishes “Polyfill supply-chain attack”. [Sansec]
  2. Cloudflare publishes “Replacing polyfill.io links with Cloudflare’s mirror”. [Cloudflare]
  3. Censys publishes “Polyfill.io: web of compromised domains”. [Censys]

Methodology

AI-assisted source research and drafting. Synthesis of the linked public primary documents, prepared on 2026-10-30. Technical conditions and dates are attributed to those documents. The decision tables, diagrams and operational interpretation are FISRO analysis. No exploit reproduction, affected-system inspection or new victim measurement was performed. Event date: 2024-06-25: event or disclosure described in the sources; source publication dates are listed separately.

Sources

Primary sources are maintainers, vendors, official bodies and original documents. Secondary sources are reporting by others.

  1. Polyfill supply-chain attack Sansec Primary Published 25 Jun 2024 Accessed 30 Oct 2026 Polyfill supply-chain attack — evidence for the incident account, technical conditions or diagnostic described here.
  2. Replacing polyfill.io links with Cloudflare’s mirror Cloudflare Primary Published 26 Jun 2024 Accessed 30 Oct 2026 Replacing polyfill.io links with Cloudflare’s mirror — evidence for the incident account, technical conditions or diagnostic described here.
  3. Polyfill.io: web of compromised domains Censys Primary Published 2 Jul 2024 Accessed 30 Oct 2026 Polyfill.io: web of compromised domains — evidence for the incident account, technical conditions or diagnostic described here.

Updates and corrections

No substantive updates or corrections since publication.

Found an error? Request a correction. We record every substantive change on this page, as set out in our corrections policy.

Related coverage