Skip to content

fix(cli): clear the 5 npm audit advisories a fresh scaffold reports - #1419

Merged
vivek7405 merged 1 commit into
mainfrom
fix/scaffold-audit-advisories
Aug 15, 2026
Merged

fix(cli): clear the 5 npm audit advisories a fresh scaffold reports#1419
vivek7405 merged 1 commit into
mainfrom
fix/scaffold-audit-advisories

Conversation

@vivek7405

@vivek7405 vivek7405 commented Aug 15, 2026

Copy link
Copy Markdown
Collaborator

Closes #1418

Summary

A freshly created app reported 5 high-severity npm audit advisories the moment webjs create finished installing, which is the first thing anyone sees after scaffolding. All 5 are one advisory (GHSA-jmr9-qjv8-65gv, an unvalidated symlink path traversal in extract-zip) reached through one chain, and the generated package.json now pins a puppeteer-core floor that clears it.

What was actually wrong

@web/test-runner@0.20.2
  -> @web/test-runner-chrome@0.18.1
    -> puppeteer-core@24.43.1
      -> @puppeteer/browsers@2.13.2
        -> extract-zip@2.0.1

Two things kept this from being a real exposure, and both are worth stating because they are why the fix is a one-line floor rather than a dependency swap. It is a devDependency, never reachable from an app's runtime. And a scaffolded app does not execute that code at all: templates/web-test-runner.config.js launches browsers through playwrightLauncher({ product: 'chromium' }), so the puppeteer chrome launcher is dead weight that @web/test-runner pulls in unconditionally through its own hard dependency on @web/test-runner-chrome. There is no supported way to install the runner without it, so the choice was between overriding the transitive version and living with the advisory.

Why the floor sits at puppeteer-core

extract-zip has no patched version. The advisory covers *, and 2.0.1 is the newest release, so an override on extract-zip itself resolves nothing. One level up does: @puppeteer/browsers@3.x dropped extract-zip entirely (it unpacks with modern-tar), and puppeteer-core@25.x depends on that 3 line.

puppeteer-core@24.43.1  ->  { "@puppeteer/browsers": "2.13.2", ... }   exact pin, vulnerable
puppeteer-core@25.7.0   ->  { "@puppeteer/browsers": "3.2.0",  ... }   clean

puppeteer-core@24.43.1 pins @puppeteer/browsers exactly, with no caret, so npm cannot dedupe its way out and an explicit overrides entry is the only lever. It is a caret rather than an exact pin because this is a security floor and a generated app should pick up later 25.x patches, which is deliberately the opposite of the drizzle-orm reasoning a few lines above it, where the exact pin exists because the scaffold source is written against one rc API.

Rejected: bumping @web/test-runner to ^1.0.0

This is what npm audit fix --force proposes, and it does not fix the advisory. @web/test-runner@1.0.0 depends on @web/test-runner-chrome@^1.0.0, which still declares "puppeteer-core": "^24.0.0", so the same vulnerable chain resolves. Taking a breaking major that leaves the audit red is strictly worse than the override, so the v1 line stays out of this PR.

Verification

Generated an app from this branch's scaffoldApp and installed it for real:

  • npm audit reports found 0 vulnerabilities, down from 5 high severity vulnerabilities on main. npm ls extract-zip in that app now returns an empty tree, so the package is not installed at all rather than installed at a tolerated version.
  • npm test in a scaffolded app passes, 8 tests across the server and browser layers, 0 failed, with browser tests launching Chromium through Playwright exactly as before. This is the half that matters for the override, since it forces a version outside @web/test-runner-chrome's declared ^24.0.0 range.

Test plan

  • test/scaffolds/scaffold-integration.test.js asserts the override is emitted, for the full-stack and api templates alike, since the manifest is shared and a later isApi branch could silently drop it from one
  • Counterfactual, proven at 4b8cd65: reverting only packages/cli/lib/create.js to its parent state reds that test with full-stack overrides puppeteer-core past the @puppeteer/browsers@2 line, and restoring it greens again
  • Full test/scaffolds/scaffold-integration.test.js suite, 13 passed, 0 failed
  • Manual audit verification on a real install (above), which is the half a unit test cannot reach, because it cannot install from the network

Surfaces

  • Tests: updated, test/scaffolds/scaffold-integration.test.js. Browser, e2e, and Bun layers are N/A because this changes one key in the manifest the scaffold writes and touches no runtime code, no served bytes, and nothing runtime-sensitive.
  • Dogfood apps: N/A because nothing in packages/core, packages/server, the dist build, or the importmap changed. examples/blog and website do not read the scaffold manifest.
  • Docs: N/A because no public API, CLI flag, or config key changed. The reasoning is documented where it can rot the least, in a comment on the override itself, so a future reader does not delete it as unexplained cruft.
  • MCP, editor plugins, marketing copy, version bumps: N/A, none of those surfaces are touched.

A freshly created app reported 5 high-severity advisories the moment
scaffolding finished, all of them GHSA-jmr9-qjv8-65gv in extract-zip,
reached through @web/test-runner's unconditional dependency on
@web/test-runner-chrome and its puppeteer-core@24 chain.

extract-zip has no patched version, so the floor has to sit at
puppeteer-core: its 25 line moved to @puppeteer/browsers@3, which
dropped extract-zip entirely. The scaffold launches browsers through
Playwright, so none of that puppeteer code was ever executed by a
generated app in the first place.
@vivek7405 vivek7405 self-assigned this Aug 15, 2026
@vivek7405
vivek7405 marked this pull request as ready for review August 15, 2026 07:42
@vivek7405
vivek7405 merged commit 818c27b into main Aug 15, 2026
10 checks passed
@vivek7405
vivek7405 deleted the fix/scaffold-audit-advisories branch August 15, 2026 07:51
vivek7405 added a commit that referenced this pull request Aug 15, 2026
Ships the scaffold audit fix from #1419, so that `npm create webjs` stops
emitting apps that report 5 high-severity advisories on their first
install. The fix only reaches users through a published `@webjsdev/cli`,
since `create-webjs` resolves it from the registry.

The changelog is hand-written rather than generated. The generator
matches conventional subjects in the package tree, and the unreleased
log for `@webjsdev/cli` also carries the `feat:` subject from #1414,
whose work was fully reverted by #1417. That revert landed with a
`revert:` prefix the generator does not match, so an auto-generated
entry would have advertised a feature that is not in the code.
@vivek7405 vivek7405 mentioned this pull request Aug 15, 2026
4 tasks
vivek7405 added a commit that referenced this pull request Aug 15, 2026
Ships the scaffold audit fix from #1419, so that `npm create webjs` stops
emitting apps that report 5 high-severity advisories on their first
install. The fix only reaches users through a published `@webjsdev/cli`,
since `create-webjs` resolves it from the registry.

The changelog is hand-written rather than generated. The generator
matches conventional subjects in the package tree, and the unreleased
log for `@webjsdev/cli` also carries the `feat:` subject from #1414,
whose work was fully reverted by #1417. That revert landed with a
`revert:` prefix the generator does not match, so an auto-generated
entry would have advertised a feature that is not in the code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dogfood: a fresh scaffold reports 5 high-severity npm audit advisories

1 participant