
JFrog: npm v12
JFrog's Security Research Team breaks down npm v12's core security change: lifecycle scripts, Git-based dependencies, and remote URL dependencies will be blocked by default and require explicit approval (allowScripts, --allow-git, --allow-remote flags), reversing npm's historical implicit-execute-on-install model. The article ties each control to real campaigns — Shai-Hulud variants abusing preinstall/postinstall hooks, easy-day-js typosquatting a dayjs dependency, CanisterWorm's Python backdoor via postinstall, and the PhantomRaven remote-dynamic-dependency campaign — and predicts attackers will pivot to compromising already-trusted scripted packages and shifting to runtime (import-time/invocation-time) execution to evade the new installation-time controls.
What it is
JFrog's analysis of npm v12 (estimated release July 2026), which flips three high-risk installation vectors from enabled-by-default to blocked-by-default, moving npm from implicit to explicit trust. The three controls: allowScripts (lifecycle script execution), --allow-git (Git repo installs, direct and indirect), and --allow-remote (remote URL installs, direct and indirect). JFrog attributes ~53% of the past year's malicious npm attacks to these three vectors combined.
How it works
allowScripts is a package.json configuration field — notably, it was already introduced in v11.10.0 (February 2026), not v12. It dictates which third-party packages may run lifecycle scripts (preinstall, install, postinstall, prepare) during npm install. In v12 it defaults to off, so third-party packages cannot execute lifecycle scripts unless explicitly approved.
A non-obvious detail: this also blocks native node-gyp builds. A package carrying a binding.gyp but no explicit install script triggers an implicit node-gyp rebuild, which can execute shell commands embedded in <!(...) expressions at install time — so the gyp path was itself an execution vector.
Preconditions / Affected
Lifecycle-script abuse accounted for 46% of malicious npm packages JFrog saw over the past year, most abusing preinstall/postinstall. The --allow-git/--allow-remote risk applies to transitive dependencies too, not just what you install directly — unvetted external code enters the graph indirectly. The easy-day-js case shows the caret trap: a clean typosquat published as easy-day-js@1.11.21 was pulled in via "easy-day-js": "^1.11.21", then the malicious 1.11.22 (postinstall payload) was auto-fetched by the range on the next install.
What to do
The page's actionable takeaway is that you need not wait for v12's July 2026 release — the allowScripts allowlist field exists as of npm v11.10.0 (Feb 2026). Adopt it now to gate which packages may run install scripts, rather than relying solely on external scanners.
Named campaigns to check exposure against:
- Shai-Hulud "Here We Go Again" — compromised hundreds of packages via malicious
preinstall; example payload was@uipath/codedagent-tool@1.0.1runningpreinstall: node setup.mjs. - Shai-Hulud "Miasma" (May–June 2026) —
@redhat-cloud-servicesnamespace, 31 compromised versions. - easy-day-js (June 2026) — typosquat of dayjs (47M weekly downloads); malicious
easy-day-js@1.11.22. - CanisterWorm (March 2026) —
@emilgroupand@teale.ionamespaces.
Caveats
v12 is an estimated July 2026 release; the defaults described are not yet shipped. JFrog's 46% lifecycle-script figure and other counts are stated to exclude a dataset the post abbreviates ("Big Red"/"Bid Red"), so headline percentages carry that scoping.
Organisations named here
- Astral Injection
- easy-day-js
- Remote Dynamic Dependencies
- Shai-Hulud
Technologies named here
- npm
- allowScripts
- @uipath/codedagent-tool
- --allow-git
- easy-day-js
- --allow-remote
- @redhat-cloud-services namespace packages
- approve-scripts
- --ignore-scripts
- @emilgroup and @teale.io namespace packages
- JFrog Security Research Center/Team
- esbuild
- Puppeteer
- node-sass
- @acme-types/acme-package
- @antv/setup
- @sap/setup
- @kindo/selfbot
- @validate-ethereum-address/core
- aes-core-valid-ipherv
- node-gyp
- Bun
Techniques named here
- Lifecycle script abuse
- Implicit node-gyp rebuild abuse
- Git-based dependency resolution abuse
- Remote Dynamic Dependencies / remote URL dependency abuse
- optionalDependencies abuse for Git fetch
- Import-time execution
- Runtime Invocation
- Hiding malicious functionality in transitive dependencies
- Dual execution path design
- Credential theft and CI/CD compromise
- Worm-like propagation
Threat actors named here
- Shai-Hulud
- easy-day-js campaign
- CanisterWorm
- PhantomRaven
- Astral Injection campaign
- Crypto Stealer campaign
- Miasma
Related in Supply Chain


