Skip to content

Security: puppeteer 25 and basic-ftp override, npm audit 11 → 0 (GHSA-7pqw-9j4j-h8q3, GHSA-jmr9-qjv8-65gv, GHSA-c475-qrg2-pj4r) - #307

Merged
SpikeyCoder merged 2 commits into
mainfrom
security/puppeteer-25
Oct 22, 2026
Merged

SpikeyCoder merged 2 commits into
mainfrom
security/puppeteer-25

Conversation

@SpikeyCoder

@SpikeyCoder SpikeyCoder commented Oct 22, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to the 2026-10-22 security sweep: clears every remaining npm audit finding in funder-finder (11 → 0).

Advisories

ID Severity Package Path Fix
GHSA-7pqw-9j4j-h8q3, GHSA-jmr9-qjv8-65gv (symlink path traversal / arbitrary file write) High extract-zip 2.0.1 (no patched release exists) puppeteer 24 → @puppeteer/browsers 2 puppeteer 24.43.1 → 25.16.0: @puppeteer/browsers 3 no longer uses extract-zip or the proxy-agent chain
GHSA-c475-qrg2-pj4r (DoS) High basic-ftp 5.3.1 @axe-core/cli → chromedriver → proxy-agent → pac-proxy-agent → get-uri overrides: basic-ftp ^6.2.3
GHSA-rxp7-6hxx-x8q5 Moderate ip-address 10.7.2 chromedriver → socks npm audit fix → 10.7.4

Reachability

  • Production: none. npm audit --omit=dev was already 0.
  • puppeteer runs only from npm run prerender (scripts/prerender.mjs), by hand, with no secrets and all cross-origin requests blocked.
  • CI: ci.yml (contents: read, no secrets) runs npm ci, which runs puppeteer's browser-download postinstall. That download is where extract-zip was actually reachable.
  • @axe-core/cli isn't called by any script or workflow. It's a manual accessibility tool.

What changed

  • package.json: puppeteer ^25.16.0; new override basic-ftp ^6.2.3. It's capped at ^6, so a future 7.x isn't pulled in unreviewed.
  • package-lock.json: regenerated with npm only.
  • .github/workflows/supply-chain-audit.yml: Node 20 → 22, since puppeteer 25 needs 22.12+. ci.yml already uses 22.
  • compliance/dep-bump-puppeteer-25-2026-10-22.md, in the repo's existing note format.

Why an override for the axe chain

@axe-core/cli 4.14.0 is the latest release, and npm's suggested fix downgrades it to 4.7.3. The override is safe because get-uri 8 calls only five basic-ftp methods (access, lastMod, list, downloadTo, close), with the same signatures in 5.3.1 and 6.2.3. basic-ftp 6.0 also turned off separate transfer hosts by default, which is a hardening against FTP bounce and only matters on the manual axe path. Remove the override once chromedriver/get-uri depend on basic-ftp ≥6.2.3.

Puppeteer 25 breaking changes checked

  • @puppeteer/browsers 3 uses proxy-agent/yauzl only if installed. They aren't, so the Chrome download ignores HTTPS_PROXY and unzips with the system unzip. CI is unaffected; a developer behind a proxy would need proxy-agent.
  • ESM-only: prerender.mjs already uses import.
  • executablePath()/defaultArgs() now return Promises: neither is used.
  • Node ≥22.12: handled by the workflow change above.

Checks run (Node 22.22, npm 10.9.4)

  • npm ci --include=optional, npm run lint, npm run build, npm test (74/74): pass
  • npm run prerender renders 6/6 routes with puppeteer 25's Chrome 156, and the output is byte-identical to the committed prerender/bodies/. No user-visible change.
  • npx axe against vite preview with the overridden basic-ftp runs end to end. It needs a Chrome matching chromedriver 152, which was already true before this PR.
    • It reports 3 existing accessibility violations on / and /mission (e.g. landmark-no-duplicate-main on #root > main). They're unrelated and left alone.
  • npm audit: 11 → 0; npm audit --omit=dev: 0 → 0.
  • Not run: the Deno edge-function tests, which this doesn't touch.

Review

/code-review and /security-review are disabled for model use in this environment, so an independent reviewer (a fresh agent that hadn't seen the work) ran both passes.

Round 1: nothing blocking. It reproduced 11 → 0, 74/74 tests, and the byte-identical prerender. It confirmed:

  • prerender.mjs is the only importer, and nothing it uses changed in v25.
  • All four workflows are on Node 22, with no engine-strict.
  • The lockfile is clean, with no new install scripts.
  • get-uri's basic-ftp calls are unchanged in 6.2.3.

Three optional findings, all handled in dfe9946:

  • The override had no upper bound. Now ^6.2.3.
  • basic-ftp 6.0's transfer-host default wasn't mentioned. Now documented.
  • The proxy-less Chrome download wasn't mentioned. Now documented.

Generated by Claude Code

…dev audit

- puppeteer ^24.43.1 -> ^25.16.0: @puppeteer/browsers@3 drops extract-zip
  (GHSA-7pqw-9j4j-h8q3, GHSA-jmr9-qjv8-65gv; no patched extract-zip
  exists) and the proxy-agent -> get-uri -> basic-ftp chain.
- overrides: basic-ftp >=6.2.3 (GHSA-c475-qrg2-pj4r) for the remaining
  @axe-core/cli -> chromedriver -> proxy-agent chain. @axe-core/cli 4.14.0
  is already latest; audit's suggested downgrade to 4.7.3 is not taken.
  get-uri@8 only uses basic-ftp Client APIs unchanged in 6.x.
- npm audit fix: ip-address 10.7.2 -> 10.7.4 (GHSA-rxp7-6hxx-x8q5).
- supply-chain-audit.yml: Node 20 -> 22 (puppeteer 25 requires >=22.12;
  matches ci.yml).

Puppeteer 25 breaking changes (ESM-only, Promise-returning
executablePath/defaultArgs, Node 22) need no code changes:
scripts/prerender.mjs is ESM and uses neither API. npm run prerender
reproduces the committed prerender/bodies byte-for-byte.

npm audit: 11 (10 high, 1 moderate) -> 0. npm audit --omit=dev: 0 -> 0.

Co-Authored-By: Claude <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Deploying funder-finder with  Cloudflare Pages  Cloudflare Pages

Latest commit: dfe9946
Status: ✅  Deploy successful!
Preview URL: https://8982a2ec.funder-finder.pages.dev
Branch Preview URL: https://security-puppeteer-25.funder-finder.pages.dev

View logs

… 3 behaviour changes

Review of #307: the override had no upper bound, so a regenerated
lockfile could pull in a future basic-ftp 7 unreviewed. Also documents
two behaviour changes the review found: basic-ftp 6.0's
allowSeparateTransferHost default (a hardening against FTP bounce), and
@puppeteer/browsers 3 skipping proxy-agent/yauzl when they are not
installed (the Chrome download ignores HTTPS_PROXY and uses system unzip).
npm audit 0; tests and lint pass.

Co-Authored-By: Claude <noreply@anthropic.com>

Copy link
Copy Markdown
Owner Author

Review round 1 (independent): nothing blocking; three optional findings (override upper bound, two undocumented behaviour changes) handled in dfe9946 — a version cap and documentation only, npm audit 0, 74/74 tests, lint, build and Pages preview green. Marking ready for review.


Generated by Claude Code

@SpikeyCoder
SpikeyCoder marked this pull request as ready for review October 22, 2026 21:57
@SpikeyCoder
SpikeyCoder merged commit ecb2810 into main Oct 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants