Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
dda2bbd
fix: combine security CVE fixes from #484 and #485, pin webpack for c…
fabiankaegy May 5, 2026
c655757
fix: pin @types/node to ^20 to satisfy npm ci strict resolution
fabiankaegy May 5, 2026
acdbe4e
fix: drop Node 16/18 support, add stylelint override, fix prettier lint
fabiankaegy May 5, 2026
1209fbd
fix: normalize eslint-config fixture paths to forward slashes for Win…
fabiankaegy May 5, 2026
4acca77
fix: use cwd-relative globs in eslint-config fixture for Windows
fabiankaegy May 5, 2026
73db8d2
fix: list eslint-config fixture files explicitly instead of globbing
fabiankaegy May 5, 2026
0da8c45
chore: bump changeset to minor
fabiankaegy May 5, 2026
cbdff41
fix: bump webpackbar to ^7 and align workspace node engines
fabiankaegy May 5, 2026
d8782e4
chore: drop unnecessary overrides covered by major plugin bumps
fabiankaegy May 5, 2026
254dc6d
fix: strip drive letter in entry.js block-asset path comparison
fabiankaegy May 5, 2026
e3d5347
fix: address PR feedback — entry.js cross-platform, sort fixtures, cl…
fabiankaegy May 5, 2026
600a704
fix: drop 3 of 6 overrides by depending on @linaria/webpack5-loader d…
fabiankaegy May 5, 2026
082aa93
fix: don't re-resolve stylesheet paths in entry.js
fabiankaegy May 5, 2026
edb631a
webpack-dev-server error fix, linaria error fix
marcovega May 13, 2026
6ad7211
fix: reconcile security branch with node 24 support on develop
fabiankaegy Aug 18, 2026
255421b
fix: address security advisories filed since the original CVE sweep
fabiankaegy Aug 18, 2026
e2014fc
fix: back out sharp bump, it breaks npm ci on linux and windows
fabiankaegy Aug 18, 2026
4ba2754
Merge branch 'develop' into fix/security-cves-combined
fabiankaegy Aug 18, 2026
1ae6f06
fix: strip react-refresh from linaria babel config on windows too
fabiankaegy Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .changeset/security-vulnerability-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
"10up-toolkit": minor
---

Security: Fix critical and high severity CVEs in transitive dependencies

Minimum Node.js version is now 20.9. The major dependency bumps required
for the security fixes (copy-webpack-plugin@^14, image-minimizer-webpack-plugin@^5)
require Node ≥20.9. Node 16 and 18 are EOL and no longer supported.

- Bump `copy-webpack-plugin` from ^11 to ^14 — resolves serialize-javascript RCE (GHSA-5c6j-r48x-rmvq) and CPU exhaustion (GHSA-qj8w-gfj5-8c6v)
- Bump `image-minimizer-webpack-plugin` from ^3 to ^5 — same serialize-javascript fix
- Downgrade `@linaria/*` from ^5 to ^4.5.4 in 10up-theme — removes happy-dom@10 CVE-2024-53382
- Bump `webpackbar` from ^6 to ^7 — webpack 5.96+ added stricter ProgressPlugin schema validation that webpackbar 6 fails by passing non-schema options to its `ProgressPlugin` parent; webpackbar 7 routes those options to a separate instance and is forward-compatible. Avoids needing to pin webpack downstream.
- Switch the toolkit's linaria integration from the meta-package `@linaria/webpack-loader` to `@linaria/webpack5-loader` directly. The meta-package always installs **both** the webpack 4 and webpack 5 loaders, dragging webpack@4.47.0 (and a long tail of vulnerable transitive deps — `serialize-javascript@<7.0.5`, `braces@2`, `micromatch@3`, `terser-webpack-plugin@1`, etc.) into every install even though only webpack 5 is used. Importing the webpack5 loader directly drops the webpack 4 chain entirely, fixing those CVEs at the dep-tree level instead of via root-level `overrides` (which don't propagate to consumers of the published `10up-toolkit`).

**Migration for `10up-toolkit` consumers using linaria:** replace `"@linaria/webpack-loader"` with `"@linaria/webpack5-loader"` in your project's `package.json` and update any `loader: '@linaria/webpack-loader'` references in custom webpack configs. No API changes — the webpack5 loader is the same module the meta-package was delegating to.
- Bump `engines.node` to `>=20.9.0` across the toolkit, eslint-config, stylelint-config, and 10up-theme workspaces. Update CI matrix to test on Node 20 + 22 only.

Reduces critical/high vulnerabilities to 0. The serialize-javascript / braces / micromatch fixes propagate to consumers via the linaria webpack5-loader swap. Remaining low/moderate issues are in dev tooling (`@wordpress/env`, `jest-environment-jsdom`, etc.) with no upstream fixes available yet.

### Note on remaining monorepo-only `overrides`

The root `package.json` keeps three `overrides` as documented temporary workarounds. npm only honors `overrides` declared in the top-level project, so these apply only to this monorepo's `npm install` / `npm ci` — they do **not** flow through to consumers installing `10up-toolkit` as a dependency. None of the three are blocking consumer security:

- `minimatch: ^9.0.7` — patches a ReDoS in `@typescript-eslint@^6`'s pinned minimatch. Resolved permanently by upgrading `@typescript-eslint` to v8 (deferred — major bump on `@10up/eslint-config` with consumer impact).
- `stylelint-declaration-strict-value: ~1.10.11` — keeps the plugin on the stylelint 15 line. The 1.11.x line bumped its peer to stylelint ≥16, conflicting with `@10up/stylelint-config`'s stylelint 15 peer. Resolved by upgrading the stylelint config to v16 (deferred — major bump with consumer impact).
- `@types/node: ^20.19.0` — workaround for `@manypkg/find-root@1`'s legacy `@types/node@^12.7.1` declaration, which conflicts with `@inquirer/external-editor`'s `@types/node>=18` peer. Upstream blocker: `@changesets/cli@2.x` still ships with `@manypkg/find-root@1`; only the `@changesets/cli@3.0.0-next.2` pre-release has migrated.

### Follow-up security bumps (added when restacking onto Node 24 support)

New advisories landed against the original set of fixes. Additionally addressed:

- Bump `postcss` from `^8.4.31` to `^8.5.26` — resolves path traversal in previous-source-map auto-loading via `sourceMappingURL` (GHSA-6g55-p6wh-862q and its incomplete-fix follow-up).
- Bump `svgo` from `^3.2.0` to `^4.0.2` — resolves the `removeScripts` advisory, where the plugin left some executable scripts intact. This is directly relevant since this is the code path that sanitises project SVGs.

**Migration for consumers with a custom `svgo.config.js`:** svgo 4 removed `removeViewBox` from `preset-default`, and changed parts of the plugin config format. The toolkit's own default config was updated accordingly (viewBox is preserved by default in svgo 4, so the previous `overrides: { removeViewBox: false }` is both unnecessary and no longer valid). Custom svgo configs written for svgo 3 may need updating — see the [svgo 4 release notes](https://github.com/svg/svgo/releases).
- Bump `@wordpress/env` in `projects/10up-theme` from `^10.10.0` to `^11.13.0` — dev-only, resolves an `extract-zip` symlink path traversal.

### Known remaining advisories

`npm audit` still reports issues that are **not** fixable within this PR:

- **`sharp` (high) — inherited libvips CVEs.** `sharp@^0.35.3` fixes these and its `engines.node >=20.9.0` matches this branch's floor exactly, but it cannot land here yet. From 0.33 onward sharp ships its prebuilt binaries as per-platform optional dependencies (`@img/sharp-linux-x64`, `@img/sharp-win32-x64`, …), and npm only records the *host* platform's entries in the lockfile — `--os`/`--cpu` are ignored, even on a from-scratch resolution. A lockfile generated on macOS therefore breaks `npm ci` on Linux and Windows with *"Could not load the `sharp` module using the linux-x64 runtime"*. Landing it needs the lockfile regenerated on Linux (or in CI). Two things to carry over when that happens: sharp reports `.avif` input as format `heif`, and 0.35 requires an explicit compression, so `config.heif` must become `{ ...config.avif, compression: 'av1' }` (verified byte-identical to the old `avif()` output); a `NOTE` to that effect is left in `optimization.js`.

- **`webpack-dev-server` (2 critical, several high/moderate — `shell-quote`, `websocket-driver`, `ws`, `http-proxy-middleware`, `sockjs`, `launch-editor`).** Every one of these comes through `webpack-dev-server`, and the whole 5.x line is affected — the only fix is `webpack-dev-server@6`, a major upgrade with dev-server config changes that deserves its own PR and HMR testing. These affect the local dev server only, not built output.
- **`@wordpress/env` → `@wp-playground/*` → `adm-zip`, `tmp` (dev-only).** `@wordpress/env@11.13.0` is the latest release and still pulls `adm-zip@0.5.x`; needs an upstream fix.
- **`postcss@8.5.14` still present in this monorepo's tree**, hoisted via `stylelint@15` / `cssnano` transitives. Consumers of the published `10up-toolkit` are not affected, because the toolkit declares `postcss@^8.5.26` and npm resolves a single satisfying copy for `postcss-loader`. Clearing it here depends on the deferred `stylelint@16` upgrade.
- **`immutable` (via `sass`), `js-yaml` / `brace-expansion` (via the `eslint@8` chain), `form-data` / `ws` (via `jsdom` in tests).** All build/test-time only, awaiting upstream releases.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The `develop` branch is the development branch which means it contains the next

### System requirements

- [Node.js](https://nodejs.org/) >= 20.0.0. Node 24 is the version we develop against — run `nvm use` to pick it up from `.nvmrc`.
- [Node.js](https://nodejs.org/) >= 20.9.0. Node 24 is the version we develop against — run `nvm use` to pick it up from `.nvmrc`.

## Get the project running
1. Clone the project `git@github.com:10up/10up-toolkit.git` somewhere.
Expand Down
Loading
Loading