Threatstealth
Threat Intel 2026-05-14 17 min read

Anatomy of a Supply Chain Compromise: How a Poisoned Build Dependency Persisted for 23 Days

A compromised npm package silently exfiltrated CI/CD environment variables — including cloud credentials and signing keys — for 23 days before detection. Here is the complete attack chain and where it could have been stopped.

By Threatstealth Threat Research

This analysis is a reconstructed case study of a software supply chain attack pattern observed across multiple incidents in early 2026. Specific identifying details have been changed. The attack chain, exfiltration mechanism, and detection gap analysis are accurate representations of real incident characteristics.

This analysis is presented for defensive purposes. The goal is to identify where defensive controls should be placed to interrupt this attack class.

Stage 1 — Initial Compromise of the Package Maintainer

The attack began with the compromise of a widely-used build tooling package on npm. The package had 2.3 million weekly downloads and was used as a devDependency in the affected organisation's CI pipeline. The package maintainer's npm account was compromised via credential stuffing — the maintainer reused a password that had appeared in a prior breach. npm accounts without MFA enabled have no second factor to block this.

Within 4 hours of account takeover, the attacker published a new minor version (2.4.1 → 2.4.2) of the package. The published version was functionally identical to 2.4.1 with one addition: a post-install script that exfiltrated environment variables to an attacker-controlled endpoint.

Stage 2 — Propagation via Automated Dependency Updates

The affected organisation used Renovate Bot to automatically merge minor and patch version bumps for devDependencies. The malicious 2.4.2 version qualified as a minor bump and was automatically merged into the main branch within 18 minutes of publication. The CI pipeline ran on the next commit — 2.4 hours after the merge.

This is the critical architectural fact: the automated dependency update pipeline created a path from an npm account compromise to code execution in the organisation's CI environment with no human approval step.

Stage 3 — Exfiltration (Days 1–23)

The post-install script executed on every CI pipeline run. Each run exfiltrated the complete set of environment variables available during the build phase. These included: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with EC2 and S3 permissions, a code signing certificate private key, a Docker Hub push token, and Slack webhook URLs.

The exfiltration HTTP request was designed to appear legitimate: it used a TLS-encrypted HTTPS connection, the destination domain resolved to a CDN IP, the User-Agent was set to a common npm tool, and the payload size was kept under 4KB to avoid anomaly detection thresholds.

Detection Gap: 23 Days

The compromise was not detected until Day 23, when a threat intelligence feed flagged the exfiltration domain as a newly registered domain used in infrastructure linked to a known threat actor. The flag triggered a SIEM rule that correlated outbound connections to newly-registered domains against CI runner IPs — a rule added three months earlier after a similar industry incident.

Without that specific SIEM rule, there was no other detection in place: no SCA scanning of post-install scripts, no egress filtering on CI runner network traffic, no alerting on new outbound HTTPS destinations from build infrastructure.

Where Six Controls Would Have Stopped This

Kill Chain Interruption Points and Missing Controls
StageAttack actionMissing controlRecommended control
Stage 1npm account credential stuffingNo MFA on npm accountEnforce MFA on all package registry accounts; monitor for credential exposure in breach feeds
Stage 2Automated minor-version mergeAuto-merge included devDependencies with post-install scriptsRestrict auto-merge to lockfile-committed, checksum-verified packages; require human review for post-install script additions
Stage 2Malicious package publishedNo SCA scan on post-install script contentRun SCA tooling that flags packages with newly-added post-install/pre-install scripts on version bumps
Stage 3Environment variable exfiltrationNo egress filtering on CI runnersEnforce deny-by-default egress policy on all CI runner networks; allowlist only required external endpoints
Stage 3HTTPS to attacker domainNo newly-registered domain detectionSIEM rule: alert on outbound connections from CI/CD infrastructure to domains registered <30 days
Stage 3Credential use post-exfiltrationNo AWS credential anomaly detectionEnable CloudTrail + GuardDuty; alert on API calls from IPs not in organisational IP ranges