Dependency overrides

Last updatedView as Markdown

Every npm dependency in this repo is development tooling. There is no src/, no block.json and no webpack config, so wp-scripts build compiles nothing; node_modules, package.json and package-lock.json are all excluded from the release zip by .distignore. Nothing here reaches production or a user — npm's only real jobs in this project are husky + commitlint for the commit-message hook.

That means these advisories carry no runtime risk. They are still worth closing: the tooling runs on developer machines and in CI, and an empty npm audit is what keeps the Dependabot queue from refilling with one PR per transitive package (it previously held 22).

The overrides block in package.json exists because a handful of transitive pins inside @wordpress/scripts block fixes that upstream has already shipped elsewhere. @wordpress/[email protected] is already the latest release, so there is no version to upgrade to, and npm audit fix moves nothing on its own (it reports 32 → 32). npm's own suggestion to "fix" this by installing @wordpress/[email protected] is a downgrade and is wrong.

Who maintains these

Renovate, not Dependabot. Renovate's npm manager treats overrides as a first-class dependency type, so it opens PRs bumping these pins as upstream releases land. Dependabot cannot: it bumps declared ranges and lockfile entries only, with no mechanism to author or update an override — which is exactly why this repo accumulated 22 open Dependabot PRs, one per transitive package, none of which any declared dependency could reach. .github/dependabot.yml disables Dependabot version updates for that reason and groups any future security updates into a single PR.

Validation: .github/workflows/override-check.yml runs bin/check-overrides.mjs weekly and on PRs touching package.json. It re-resolves the tree without overrides and audits it — if an override's package no longer audits as vulnerable, upstream shipped the fix and the job fails to tell us to delete the override. Renovate keeps @wordpress/scripts current, so upstream fixes arrive on their own; the check turns them into a removal signal.

Active overrides

Six overrides clear all 32 advisories. Each fixes a whole cluster, so the list is deliberately shorter than the advisory count — pinning the leaves as well (an earlier draft pinned 20 packages) is redundant once the parent moves.

They are nested (parent-scoped) rather than global. "adm-zip": "^0.6.0" at the top level would force that version everywhere in the tree; nesting it under @wordpress/scripts changes only the path that actually needs it, so a future dependency that legitimately wants a different major is unaffected. It also makes each entry self-documenting — the parent named in package.json is the blocking pin. Verified equivalent: both forms produce zero advisories and a single copy of each package, with no duplicate left behind at a vulnerable version.

OverrideBlocking pinClearsRemove when
lighthouse → @sentry/node: ^10.70.0lighthouse pins @sentry/node@^9.28.116 entries: @sentry/node plus the whole @opentelemetry/* set (core, resources, sdk-trace-base, sql-common and 12 instrumentation-*). Sentry 9 pins the @opentelemetry/[email protected] line, which carries an unbounded-memory advisory fixed in otel 2.8 / Sentry ≥ 10.54.lighthouse allows @sentry/node ≥ 10.54
lighthouse → puppeteer-core: ^25.8.0lighthouse pins puppeteer-core@^24.17.1puppeteer-core, @puppeteer/browsers, extract-zip, lighthousewp-scripts ships a puppeteer chain > 24.43.1
@wordpress/scripts → adm-zip: ^0.6.0@wordpress/scripts pins adm-zip@^0.5.9adm-zip (4 GB memory-allocation DoS, fixed in 0.6.0)wp-scripts allows adm-zip ≥ 0.6.0
@wordpress/scripts → markdownlint-cli: ^0.49.1@wordpress/scripts pins markdownlint-cli@^0.31.1 (2022-era)markdownlint-cli, markdownlint, markdown-it@12, linkify-it@3, minimatchwp-scripts modernises its markdownlint-cli pin
@wordpress/scripts → copy-webpack-plugin: ^14.0.0@wordpress/scripts pins copy-webpack-plugin@^10.2.0, which pins serialize-javascript@6copy-webpack-plugin, serialize-javascript (RCE via RegExp.flags + CPU-exhaustion DoS; all 6.x affected)wp-scripts bumps copy-webpack-plugin to a major allowing serialize-javascript 7.x
@wordpress/scripts → webpack-dev-server: ^6.0.0@wordpress/scripts pins webpack-dev-server@^5.2.1 (also reached via @pmmmwh/react-refresh-webpack-plugin, which npm dedupes to the overridden copy)webpack-dev-server, sockjs, uuid@8wp-scripts moves to webpack-dev-server ≥ 6

Risk notes

The aggressive majors here (webpack-dev-server 5 → 6, copy-webpack-plugin 10 → 14, puppeteer-core 24 → 25, uuid 8 → 14 transitively) would be risky in a project that actually ran the wp-scripts commands they back. This project runs none of them:

  • webpack-dev-server only matters to wp-scripts start, which has no source to serve here.
  • copy-webpack-plugin and serialize-javascript sit inside the webpack build, which compiles nothing — npm run build exits 0 with "Source directory 'src' was not found".
  • adm-zip backs wp-scripts plugin-zip; the release pipeline builds its zip with zip -r in .github/workflows/release-please.yml, not that command.
  • puppeteer-core, lighthouse and the Sentry/otel chain back wp-scripts' e2e and performance testing. There are no e2e tests in this repo.
  • markdownlint-cli backs wp-scripts lint-md-docs, which is not wired up.

Verified after pinning: npm run build exits 0, and commitlint still accepts a valid message and rejects an invalid one — the two things npm is actually load bearing for here.

If the check fails

bin/check-overrides.mjs exits 1 with a ✖ STALE line naming the override. Delete that entry from package.json, regenerate the lockfile (npm install --package-lock-only), confirm npm audit still reports zero, and update the table above.

One limitation to be aware of: the script strips all overrides at once before auditing, so it cannot tell that one override is redundant because a different override already fixes it transitively. That is how the earlier 20-entry list passed the check while six entries did the same job. When adding an override, check whether bumping the parent already covers it.

Have a question about this page?

Linchpin assistant

Was this helpful?