CoursesSoftware supply chain securityThreat landscape & mindset

Anatomy of real supply-chain attacks

SolarWinds, dependency confusion, Codecov, xz.

Intermediate14 min · lesson 2 of 18

The controls in this course are not abstract — each answers a real class of attack that has hit real organizations. Understanding the shapes of these attacks tells you which link failed and which defense would have caught it. They fall into a few recurring patterns: compromise the build, poison a dependency, hijack a maintainer, or exploit how resolvers choose packages.

Attack patterns and the defense that stops each
poison the inputs
dependency confusion
defense: scope + pin internal names
typosquatting
defense: pinned, reviewed deps
compromised maintainer/account
defense: verify provenance, not just source
compromise the process
tampered build system
defense: SLSA, hermetic builds
stolen CI credential
defense: OIDC, short-lived tokens
Every headline supply-chain incident maps to one of these — and to a control this course covers.

Compromise the build (SolarWinds, Codecov)

The most damaging pattern subverts the build itself: the source in the repo is clean, but the build process inserts malicious code, so the shipped artifact does not match the reviewed source. In the SolarWinds case, attackers modified the build to inject a backdoor into a signed, trusted update pushed to thousands of customers. Codecov’s CI script was altered to exfiltrate secrets from every pipeline that used it. The lesson: reviewing source is not enough if you cannot verify the build produced that source unchanged — which is exactly what SLSA and provenance address.

Poison a dependency (dependency confusion, typosquats, xz)

The other major pattern attacks what you pull in. Typosquatting publishes a malicious package with a name one keystroke from a popular one. Dependency confusion exploits resolvers that prefer a public registry: publish a public package with the same name as a company’s internal one and a higher version, and builds silently pull the attacker’s. The xz backdoor showed the long game — an attacker spent years becoming a trusted maintainer of a core compression library before planting a backdoor. These are defended by pinning, scoping internal names, and verifying provenance rather than trusting a name.

terminal
# dependency confusion in one line of intent:
# internal package "acme-auth" exists only in your private registry at 1.2.0
# attacker publishes public "acme-auth" 99.0.0
# a resolver that prefers the public registry pulls 99.0.0 — the attacker’s code
# defense: scope internal packages (@acme/auth) + pin + a resolver that never falls back to public
The clean-source illusion
The through-line of these attacks is that the code in the repository looked fine. The malicious change lived in the build, in a transitive dependency, or in a maintainer’s account — places code review never looks. That is why supply-chain security cannot stop at "we reviewed the PR"; it has to verify the dependencies, the build, and the resulting artifact independently of the source review.