npm 12 Disables Install Scripts, Git Dependencies, and Remote Tarball URLs by Default to Curb Supply-Chain Worms Like Shai-Hulud
npm 12 Disables Install Scripts, Git Dependencies, and (TL-2026-1163), also tracked as npm 12 install-script hardening, is a medium-severity supply-chain compromise, first published 2026-07-10. It has no confirmed attribution, affects npm, Inc. / GitHub (Microsoft) npm CLI, maps to 28 MITRE ATT&CK techniques (T1005, T1020, T1021.004), and is covered by 9 detection rules and 30 indicators of compromise.
Key facts for TL-2026-1163
- Threat ID
- TL-2026-1163
- Also known as
- npm 12 install-script hardening, npm allowScripts default-off change
- Severity
- MEDIUM
- Status
- MITIGATED
- Category
- SUPPLY_CHAIN
- First published
- 2026-07-10
- Last reviewed
- 2026-07-10
- Attribution confidence
- LOW
- Motivation
- UNKNOWN
- Target sectors
- technology, software-development, all-sectors-using-npm
- Target regions
- Global
- Detection rules
- 9
- Indicators of compromise
- 30
Malware and tooling in npm 12 Disables Install Scripts, Git Dependencies, and
Malware and tooling: TruffleHog - S9009
npm 12 flips the default trust model for the JavaScript package ecosystem: dependency lifecycle scripts (preinstall/install/postinstall, implicit node-gyp builds), Git-based dependencies, and remote tarball URL dependencies are now opt-in rather than automatic, requiring developers to explicitly allowlist trusted packages via 'npm approve-scripts'. The change directly targets the code-execution-at-install vector abused by self-propagating worms such as Shai-Hulud and Shai-Hulud 2.0, which used postinstall/preinstall hooks to harvest and exfiltrate hundreds of thousands of cloud and CI/CD credentials in 2025.
How npm 12 Disables Install Scripts, Git Dependencies, and works
GitHub (Microsoft) announced that npm 12, expected to ship in July 2026, changes three long-standing default installation behaviors that have been repeatedly weaponized in npm supply-chain attacks. First, `allowScripts` now defaults to off: dependency lifecycle scripts (`preinstall`, `install`, `postinstall`) and the implicit `node-gyp rebuild` invoked by native-module packages (e.g. sharp, canvas, bcrypt) no longer execute automatically on `npm install` — they require explicit approval. Second, `--allow-git` now defaults to `none`, blocking resolution of Git-sourced dependencies (direct or transitive) unless explicitly allowed. Third, `--allow-remote` now defaults to `none`, blocking resolution of dependencies fetched from remote tarball URLs (e.g. `https://...tar.gz`) unless explicitly allowed.
To restore functionality for legitimate packages, developers run `npm approve-scripts --allow-scripts-pending` to list every package whose install scripts are not yet covered by the allowlist (read-only, does not modify anything), then `npm approve-scripts <pkg>` to approve individual packages (pinned to exact version by default, or by name with `--no-allow-scripts-pin`), or `npm deny-scripts <pkg>` to explicitly block one. The resulting allowlist is committed into `package.json` so CI and other developers inherit the same trust decisions. A migration path exists via npm 11.16.0 (already available), which surfaces warnings and offers a `--strict-allow-scripts` flag to opt in to v12 behavior early; the recommended bulk-migration pattern is `npm install` → `npm approve-scripts --all` → commit, which snapshots current scripts as trusted while blocking any *new* unexpected scripts going forward — this is explicitly a stopgap, not a substitute for per-package review.
This hardening is a direct structural response to the install-script abuse pattern demonstrated at scale by the Shai-Hulud npm worm campaigns. In September 2025, the original Shai-Hulud worm (patient zero: `rxnt-authentication` v0.0.3, published Sept 14 17:58:50 UTC) used malicious `postinstall` scripts to run a bundled payload (`bundle.js`, 3MB+) that deployed TruffleHog to scan for 800+ secret types, harvested npm/GitHub/AWS/GCP tokens, then self-propagated by publishing trojanized new versions of every other package the compromised maintainer controlled — compromising over 400 packages including `@ctrl/tinycolor` (2.2M weekly downloads), `ngx-bootstrap`, and `ng2-file-upload` within roughly 24 hours, and publicly exposing stolen secrets via auto-created GitHub repositories named 'Shai-Hulud'. In November 2025, a more aggressive 'Shai-Hulud 2.0' / 'Sha1-Hulud: The Second Coming' campaign moved the payload from the `postinstall` to the `preinstall` lifecycle hook specifically so the malicious code would execute even if the rest of the package installation subsequently failed — compromising roughly 700 npm packages (including `@postman/tunnel-agent`, `posthog-node`, `posthog-js`, `@asyncapi/specs`), creating over 25,000 malicious GitHub repositories at a peak velocity of ~1,000 new repos per 30 minutes, exfiltrating 775 GitHub tokens, 373 AWS credentials, 300 GCP credentials, and 115 Azure credentials from roughly 500 compromised GitHub users. Both campaigns are attributed with only moderate confidence to a financially- or chaos-motivated actor with no named group; researchers assess with moderate confidence that an LLM was used to help generate the malicious bash scripts (based on comment style and emoji usage in the code).
npm 12 is one plank of a broader npm ecosystem hardening timeline disclosed alongside it: from early August 2026, Granular Access Tokens (GATs) configured to bypass 2FA will lose the ability to perform sensitive account operations (token management, password/email changes, 2FA configuration, package-access changes, organization management); from January 2027, GATs will no longer support direct package publishing at all — publishing will require staged releases pending human 2FA approval. Separately, the competing package manager pnpm shipped version 11.10 with a new `_auth` registry-authentication setting designed to stop malicious project files from redirecting a developer's valid registry token to an attacker-controlled host — a related but independently-shipped mitigation for token-theft-via-redirect, not part of the npm 12 change itself. No CVE was assigned to this change; it is a default-behavior hardening announcement, not a vulnerability disclosure, and the source article names no active exploitation of npm 12 itself (npm 12 is the fix, not the flaw).
MITRE ATT&CK techniques used in TL-2026-1163
Collection
exfiltration
Lateral Movement
T1021.004 SSH; T1021.006 Windows Remote Management
Defense Evasion
T1027 Obfuscated Files or Information
Persistence
T1053 Scheduled Task/Job; T1078 Valid Accounts; T1098.001 Additional Cloud Credentials; T1547 Boot or Logon Autostart Execution; T1547.001 Registry Run Keys / Startup Folder; T1547.013 XDG Autostart Entries
Execution
T1059 Command and Scripting Interpreter
Discovery
T1087 Account Discovery; T1526 Cloud Service Discovery; T1580 Cloud Infrastructure Discovery; T1619 Cloud Storage Object Discovery
Credential Access
T1110 Brute Force; T1528 Steal Application Access Token; T1552 Unsecured Credentials; T1552.001 Credentials In Files; T1555 Credentials from Password Stores; T1555.003 Credentials from Web Browsers; T1557 Adversary-in-the-Middle
Initial Access
T1195 Supply Chain Compromise; T1566 Phishing
Impact
Exfiltration
T1537 Transfer Data to Cloud Account
Resource Development
Affected products and versions in npm 12 Disables Install Scripts, Git Dependencies, and
- npm, Inc. / GitHub (Microsoft) — npm CLI
Vulnerable versions: npm < 11.16.0 (legacy always-run install-script behavior)
Fixed in: npm 11.16.0 (opt-in early enforcement via --strict-allow-scripts); npm 12 (enforced by default, targeted July 2026) - npm ecosystem (historical attack surface) — npm registry dependency lifecycle scripts (preinstall/install/postinstall) and node-gyp implicit builds
Vulnerable versions: all npm versions prior to 11.16.0 that auto-execute lifecycle scripts on install
Fixed in: allowlisted via npm approve-scripts under npm 11.16.0+/12 - Multiple maintainers (historical compromise, unrelated to npm 12 itself) — @ctrl/tinycolor, ngx-bootstrap, ng2-file-upload, rxnt-authentication, @postman/tunnel-agent, posthog-node, posthog-js, @asyncapi/specs
Vulnerable versions: ngx-bootstrap 18.1.4, 19.0.3-4, 20.0.3-6; ng2-file-upload 7.0.2-3, 8.0.1-3, 9.0.1; @ctrl/tinycolor 4.1.1-2; rxnt-authentication 0.0.3
Fixed in: trojanized versions removed/unpublished by npm registry; maintainers advised to republish clean versions
Remediation for npm 12 Disables Install Scripts, Git Dependencies, and
Patches
- npm 11.16.0 — available now; warns on uncovered install scripts and supports --strict-allow-scripts to opt into v12 behavior early
- npm 12 — targeted for July 2026 GA; enforces allowScripts=off, --allow-git=none, --allow-remote=none as defaults
Immediate actions
- Upgrade to npm 11.16.0+ and run 'npm approve-scripts --allow-scripts-pending' to inventory every dependency whose lifecycle scripts are not yet covered by an allowlist
- Run 'npm install' then 'npm approve-scripts --all' to snapshot currently-trusted scripts as a stopgap, then commit the resulting allowlist to package.json so CI inherits the same trust decisions
- Individually review and approve high-risk packages with 'npm approve-scripts <pkg>' (pinned to exact version) rather than blanket-approving with --all where feasible
- Explicitly deny scripts for any unreviewed or unfamiliar transitive dependency with 'npm deny-scripts <pkg>'
- Audit CI/CD pipelines and build environments for exposure from prior installs that ran unreviewed postinstall/preinstall scripts, especially around the Sept-Dec 2025 Shai-Hulud campaign window
- Rotate any npm, GitHub PAT, AWS, GCP, or Azure credentials that were present in environments where dependency installs ran unreviewed scripts
Workarounds
- Pin and audit package.json 'allowScripts' entries manually if unable to upgrade npm immediately
- Use 'npm ci --ignore-scripts' in CI/build pipelines as an interim blanket mitigation prior to adopting the granular allowlist
Longer-term hardening
- Adopt npm 12 as the enforced baseline once released (July 2026 target) and require 'npm approve-scripts' allowlist review as a standard step in dependency-update PRs
- Enforce '--strict-allow-scripts' in CI ahead of the npm 12 GA to catch newly-introduced install scripts before they reach production build environments
- Move to Granular Access Tokens (GATs) with staged, human-2FA-approved publishing ahead of the January 2027 deadline that removes direct-publish rights from GATs used to bypass 2FA
- Evaluate pnpm 11.10's '_auth' registry-auth setting (or equivalent) to prevent token redirection to attacker-controlled registries as a complementary control
- Implement dependency-install sandboxing/network egress restriction in CI so any script that does run cannot exfiltrate secrets even if approved in error
- Monitor for anomalous outbound npm-install-time network calls (e.g. to webhook.site or similar generic webhook/exfil endpoints) as a detection layer independent of the allowlist
Weaknesses (CWE) in npm 12 Disables Install Scripts, Git Dependencies, and
CWE-506, CWE-829, CWE-494, CWE-1357
Timeline of npm 12 Disables Install Scripts, Git Dependencies, and
- rxnt-authentication v0.0.3 published to npm at 17:58:50 UTC — later identified as patient zero of the original Shai-Hulud worm campaign, the postinstall-script abuse pattern npm 12 directly targets.
- ReversingLabs first detects the Shai-Hulud npm worm; over 400 compromised packages including @ctrl/tinycolor, ngx-bootstrap, and ng2-file-upload identified within roughly 24 hours of spread.
- Trend Micro and Truesec publish analyses assessing scale of Shai-Hulud campaign; hundreds of npm packages confirmed compromised, secrets publicly exposed via auto-created 'Shai-Hulud' GitHub repositories.
- Trojanized npm packages for the 'Shai-Hulud 2.0' / 'Sha1-Hulud: The Second Coming' campaign begin being uploaded to the npm registry, this time abusing the preinstall lifecycle hook instead of postinstall.
- First GitHub repositories containing leaked secrets from Shai-Hulud 2.0 created at 01:22 UTC; first malicious packages appear live on npm registry roughly 03:00 UTC same day.
- Second attack phase observed at 22:45 UTC: private repositories published using credentials stolen during phase one, escalating the campaign's reach.
- Palo Alto Networks Unit 42 publishes and updates Shai-Hulud advisory with executive summary and managed threat-hunting queries; campaign scope reaches ~25,000 malicious repositories and ~700 affected packages.
- Cortex/vendor product protections updated in response to Shai-Hulud 2.0; Zscaler and Wiz publish further technical breakdowns of the campaign's IOCs and MITRE mapping.
- Microsoft Security publishes detection, investigation, and defense guidance for Shai-Hulud 2.0, formalizing the industry response that informs npm's subsequent default-behavior hardening.
- GitHub announces npm v12 will disable install scripts, Git dependencies, and remote tarball dependencies by default; npm 11.16.0 ships with early opt-in support via --strict-allow-scripts.
- The Hacker News publishes coverage of the npm 12 default-behavior change ahead of its general-availability target, summarizing allowScripts/--allow-git/--allow-remote defaults and the npm approve-scripts workflow.
- Target general-availability window for npm 12, at which point allowScripts=off, --allow-git=none, and --allow-remote=none become enforced defaults for all npm installs.
- Granular Access Tokens (GATs) configured to bypass 2FA lose the ability to perform sensitive account operations: token management, password/email changes, 2FA configuration, package-access changes, and organization management.
- GATs lose direct package-publishing capability entirely; publishing becomes limited to reading private packages and staging releases pending human 2FA approval.
Sources cited for npm 12 Disables Install Scripts, Git Dependencies, and
- npm 12 Disables Install Scripts by Default to Reduce Supply Chain Risk
- GitHub to Disable npm Install Scripts by Default to Stop Supply Chain Attacks
- Preparing for npm v12: install scripts and non-registry sources become opt-in
- npm-approve-scripts CLI reference
- Shai-Hulud npm supply chain attack: What you need to know
- "Shai-Hulud" Worm Compromises npm Ecosystem in Supply Chain Attack
- Sha1-Hulud 2.0 Supply Chain Attack: 25K+ Repos Exposed
- Shai-Hulud 2.0: Guidance for detecting, investigating, and defending against the supply chain attack
- Shai-Hulud V2 Poses Risk to NPM Supply Chain
- 500+ npm Packages Compromised in Ongoing Supply Chain Attack 'Shai-Hulud'
- What We Know About the NPM Supply Chain Attack
Threats related to npm 12 Disables Install Scripts, Git Dependencies, and
- Miasma / Shai-Hulud Supply-Chain Campaign Pushes Password-Stealing Malware via Compromised Microsoft GitHub Repos (durabletask PyPI 1.4.1-1.4.3)
- Shai-Hulud npm Supply-Chain Worm: Two Alleged TeamPCP Members Charged by AFP/FBI
- Keyv and Cacheable npm Supply Chain Attack via Compromised Maintainer Account (Shai-Hulud Malware)
- GitHub and PyPI Add Time-Based Defenses Against Supply-Chain Attacks
- Malicious npm Package 'shai_hulululud' (v1.0.48596): Prompt Injection, AI-Safety Triggering, and Token Flooding to Evade AI Malware Scanners (Shai-Hulud Lineage)
- ChainDrop/Mini Shai-Hulud npm Worm Compromises keyv, cacheable, and 400+ Downstream Packages via Ethereum-Resolved C2
Detection coverage for TL-2026-1163
As of 2026-07-10, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-1163 across Splunk SPL, Microsoft KQL and Sigma, covering 30 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.