Skip to content

Commit f731f0a

Browse files
committed
LTS-4750: drop extract-zip via @puppeteer/browsers 3.x override (GHSA-jmr9-qjv8-65gv)
extract-zip is abandoned — the advisory range is `<= 2.0.1` and 2.0.1 is `latest` (published 2020), so `first_patched_version` is null. There is no version to bump to. The only copy in this tree comes from `@wdio/utils` -> `@puppeteer/browsers` `^2.2.0`. `@puppeteer/browsers` 3.x replaced extract-zip with its own extractor, which validates symlink targets before creating them: if (!isInsideDirectory(folderPath, resolvedLinkTarget)) { throw new Error(`Zip symlink "..." would point outside of the target directory.`) } So overriding `@puppeteer/browsers` to `^3.1.0` removes the vulnerable package rather than papering over it. That drops extract-zip, @types/yauzl, fd-slicer, progress and yauzl@2 from the tree and takes `npm audit` from 12 high to 0 high (all 12 were the same extract-zip root, re-reported up the @wdio/* chain). 3.x makes `proxy-agent` a peerDependency (`>=8.0.1`) instead of a hard dep, so npm pulls a refreshed proxy-agents subtree (proxy-agent 8.0.2, pac-* 9, degenerator 7 + quickjs-wasi, http/https-proxy-agent 9 + proxy-agent-negotiate, socks-proxy-agent 10). All are TooTallNate / vercel-labs / sindresorhus packages and carry no advisories. Pinned to 3.1.0 in the lock (published 2026-08-04) rather than 3.2.0 (2026-08-11) so the `.npmrc` `min-release-age=7` cooldown is respected; the `^3.1.0` range lets it float once 3.2.0 clears it. `engines.node` goes `>=18` -> `>=22.12.0`: @puppeteer/browsers 3.x is ESM-only and sets that floor itself, and with `engine-strict=true` the root floor has to agree or customers get the error from a transitive dep instead of from us. Node 18 (EOL 2025-04-30) and Node 20 (EOL 2026-04-30) are both out of support. Verified: - `npm ci` clean: 0 high / 0 critical (was 12 high); 6 moderate remain (qs/uuid via googleapis <- browserstack-node-sdk), unticketed and below this repo's own `audit-level=high` gate. - No `extract-zip` anywhere in the installed tree. - PoC on a zip carrying `pwned -> ../../../../../../../../../../tmp/lts4750-escape`: extract-zip@2.0.1 writes the symlink and it resolves to /tmp/lts4750-escape, outside the extraction dir; @puppeteer/browsers@3.1.0 rejects it with "would point outside of the target directory" and leaves nothing behind. - Full local run through the real code path (`npx wdio run`): Chromedriver v150.0.7871.189 downloaded and unpacked from a .zip by 3.1.0 (the former extract-zip call site), driver started, live WebDriver session against bstackdemo.com, add-to-cart spec passing.
1 parent 1e0a8c8 commit f731f0a

3 files changed

Lines changed: 407 additions & 171 deletions

File tree

.npmrc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
# postinstalls (edgedriver/geckodriver) are not needed. browserstack-node-sdk is
1010
# pinned to the latest release (1.61.0) so no update-postinstall is needed either.
1111
#
12-
# engine-strict=true enforces the package.json `engines.node` floor (>=18), which
13-
# matches our runner pod and what @wdio/cli 9 already requires. Customers on EOL
14-
# Node (<18) get a clear upgrade message instead of obscure failures.
12+
# engine-strict=true enforces the package.json `engines.node` floor (>=22.12.0).
13+
# The floor was raised from >=18 for LTS-4750: the only fix for the unpatched
14+
# extract-zip path traversal (GHSA-jmr9-qjv8-65gv) is @puppeteer/browsers 3.x,
15+
# which is ESM-only and requires Node >=22.12.0. Node 18 (EOL 2025-04-30) and
16+
# Node 20 (EOL 2026-04-30) are both out of support anyway, so customers on EOL
17+
# Node get a clear upgrade message instead of obscure failures.
1518

1619
strict-ssl=true
1720
save-exact=true

0 commit comments

Comments
 (0)