oxc-project/oxc · critical · OxcDiagnostic
Using polyfill.io is a security risk due to a supply chain a
Error message
Using polyfill.io is a security risk due to a supply chain attack in 2024.
What it means
Diagnostic from the oxlint rule nextjs/no-unwanted-polyfillio (correctness category). It fires when a JSX <script> element (or a next/script component) has a string-literal src pointing at the compromised polyfill.io service: the domain was acquired by a malicious actor in a June 2024 supply-chain attack that injected hostile code into 380,000+ websites. Because the domains cdn.polyfill.io and polyfill.io are permanently tainted, any reference is reported as a security defect, not a style nit. The rule only runs on JSX sources and only matches literal src strings, so a dynamic src={'https://polyfill.io/...'} expression is not caught.
Source
Thrown at crates/oxc_linter/src/rules/nextjs/no_unwanted_polyfillio.rs:26
use oxc_semantic::AstNode;
use oxc_span::Span;
use crate::{
context::{ContextHost, LintContext},
rule::Rule,
utils::{NEXT_POLYFILLED_FEATURES, find_url_query_value, get_next_script_import_local_name},
};
fn no_unwanted_polyfillio_diagnostic(polyfill_name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"No duplicate polyfills from Polyfill.io are allowed. {polyfill_name} already shipped with Next.js."
))
.with_help("See https://nextjs.org/docs/messages/no-unwanted-polyfillio")
.with_label(span)
}
fn polyfill_io_security_warning(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(
"Using polyfill.io is a security risk due to a supply chain attack in 2024."
)
.with_help("Replace with a safe alternative like https://cdnjs.cloudflare.com/polyfill/ or use modern browser features directly. See: https://blog.cloudflare.com/polyfill-io-now-available-on-cdnjs-reduce-your-supply-chain-risk")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoUnwantedPolyfillio;
declare_oxc_lint!(
/// ### What it does
///
/// Prevent use of unsafe polyfill.io domains and duplicate polyfills.
///
/// ### Why is this bad?
///
/// **Security Risk:**
/// The domains `cdn.polyfill.io` and `polyfill.io` were compromised in a supply chain attack in 2024,View on GitHub (pinned to e1e7af627c)
Solutions
- Delete the polyfill.io <script> tag entirely and rely on the browsers/transpilation targets your project already supports
- If a polyfill is genuinely needed, switch to a safe mirror such as https://cdnjs.cloudflare.com/polyfill/ and request only features Next.js does not already ship (the rule's duplicate-polyfill check will then keep you honest)
- Prefer bundling polyfills through core-js/browserslist or importing them in _app instead of any third-party CDN
- Add nextjs/no-unwanted-polyfillio to CI with --deny-warning so the compromised domain cannot be reintroduced by template copy-paste
Example fix
// before (pages/_document.jsx or a component) <script src='https://cdn.polyfill.io/v2/polyfill.min.js'></script> // after: remove it, or use a safe mirror with only needed features <script src='https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserver'></script>
Defensive patterns
Strategy: validation
Validate before calling
# .oxlintrc.json
"rules": { "nextjs/no-unwanted-polyfillio": "error" }
# CI gate
npx oxlint -c .oxlintrc.json --deny-warning .
# belt-and-braces grep over templates (catches non-JSX HTML too)
grep -RInE 'https?://([a-z0-9.-]+\\.)?polyfill\\.io' app components public || echo clean Prevention
- Treat third-party script tags in JSX like dependencies: review them in PRs and pin to vetted CDN mirrors only
- Prefer bundler-managed polyfills (core-js/browserslist) over runtime CDN injection so URLs never enter source
- Subscribe to supply-chain advisories (GitHub Dependabot, npm advisories) so a compromised domain surfaces before lint does
When it happens
Trigger: A JSXOpeningElement whose tag name is 'script' or matches the local import name of next/script, carrying a src attribute of type JSXAttributeValue::StringLiteral whose value starts with 'https://cdn.polyfill.io/v2/' or 'https://polyfill.io/v3/'. The security warning is emitted before any other check in run() and returns early, so it takes precedence over the duplicate-polyfill diagnostic that covers cdjs.cloudflare.com/polyfill and polyfill-fastly.* URLs.
Common situations: Legacy HTML boilerplate or pre-2024 tutorials pasted into Next.js layouts; marketing pages kept a <script src='https://cdn.polyfill.io/v2/polyfill.min.js'> tag for old-IE support; teams auditing after the 2024 incident news; enabling the nextjs plugin in .oxlintrc.json for the first time on an old codebase.
Related errors
- No duplicate polyfills from Polyfill.io are allowed. {polyfi
- React 19 disallows `javascript:` URLs as a security precauti
- Using target=`_blank` without rel=`noreferrer` (which implie
- Using target=`_blank` without rel=`noreferrer` or rel=`noope
- all spread attributes are treated as if they contain an unsa
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/09a9dd20cc288fee.
Report an issue: GitHub.