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

  1. Delete the polyfill.io <script> tag entirely and rely on the browsers/transpilation targets your project already supports
  2. 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)
  3. Prefer bundling polyfills through core-js/browserslist or importing them in _app instead of any third-party CDN
  4. 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

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


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/09a9dd20cc288fee. Report an issue: GitHub.