Uh oh!
There was an error while loading. Please reload this page.
chore: harden Yarn install scripts in the JS SDK - #1019
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Install and postinstall scripts are the primary execution vector for the recent wave of npm supply-chain attacks (Shai-Hulud, nx, chalk, debug). The root .yarnrc.yml had no script hardening, so any installed package could run arbitrary code at install time in CI and on contributor machines. As a published SDK, a compromised install step would also flow out to downstream consumers. Disable build scripts globally (enableScripts: false) and allow-list only the packages that genuinely need to compile or download a binary at install time, via dependenciesMeta.<pkg>.built: true in the root package.json (Yarn 4 does not recognize dependenciesMeta in .yarnrc.yml): - @swc/core, esbuild — build toolchain (required) - sharp — native image processing (Next.js examples) - unrs-resolver — native resolver (eslint-import-resolver-typescript) msgpackr-extract (pulled in by @expo/metro-config) is left denied: it is example/dev tooling only, ships a prebuilt-binary optional dependency, and falls back to pure JS, so it does not need its install script to run. Verified on Yarn 4.9.1 that built: true re-enables only the listed packages under a global enableScripts: false (allow-list, not deny-list). Fresh install, immutable install, build:packages, type:check, lint, and the full test suite (878 tests) all pass; workspace lifecycle scripts (root postinstall: manypkg check) are unaffected.
3d5c8a8 to
cf44b3dCompareCodecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@## main #1019 +/- ##
=======================================
Coverage 63.55% 63.55% =======================================
Files 208 208 Lines 9924 9924 Branches 1280 1280 =======================================
Hits 6307 6307 Misses 3592 3592 Partials 25 25 |
Uh oh!
There was an error while loading. Please reload this page.
Description
Hardens Yarn install-script execution in the monorepo to reduce supply-chain attack surface. Closes KNO-13806.
Why. Install/postinstall scripts are the primary execution vector for the recent wave of npm supply-chain attacks — Shai-Hulud and the nx, chalk, and debug compromises all ran their payloads through a postinstall script. The root
.yarnrc.ymlhad no script hardening, so any installed package could run arbitrary code at install time, in CI and on contributor machines. As a published SDK, a compromised install step here would also flow out to every downstream consumer.What & how.
.yarnrc.yml→enableScripts: false: deny all dependency build scripts by default.package.json→ adependenciesMetaallow-list re-enables (built: true) only the packages that genuinely need to compile or download a binary at install time:@swc/core,esbuild— build toolchain (required forbuild:packages)sharp— native image processing (Next.js examples)unrs-resolver— native module resolver behindeslint-import-resolver-typescript(required forlint)dependenciesMetalives in the manifest, not.yarnrc.yml— Yarn 4.9.1 does not recognize it as a yarnrc setting (verified viayarn config+ the docs). The lockfile change is just Yarn recording that allow-list against the root workspace.Re-derived the allow-list from a fresh install rather than trusting the proposed list. A clean install surfaced one extra package with an install script:
msgpackr-extract(pulled in transitively by@expo/metro-config). It's left denied — it's example/dev tooling only, ships its native binary via a prebuilt-binary optional dependency (@msgpackr-extract/msgpackr-extract-*), and falls back to pure JS, so its postinstall doesn't need to run. That's the more-hardened choice and is explicitly sanctioned by the ticket ("only needed by examples or tooling … can stay denied").Verification — Yarn 4.9.1, all green locally:
built: trueacts as an allow-list override of a globalenableScripts: false(re-enables only the listed packages), not purely a deny-list.yarn installandyarn install --immutable(what CI runs): exactly the 4 allow-listed packages build;msgpackr-extractis denied with a warning (YN0004), not an error; no install errors;yarn.lockstays consistent under--immutable.postinstall: manypkg checkstill runs.yarn format:check,yarn build:packages,yarn type:check,yarn lint, andyarn test(74 files / 878 tests) all pass.Checklist