OWASP Top 10 2026: Software Supply Chain Failures at A03 — What Developers Must Change

The OWASP Top 10 2026 edition elevates Software Supply Chain Failures to A03, promoting it from the narrower 'Vulnerable and Outdated Components' category. CI/CD pipeline attacks are up 45% since 2022. Here's what the new category means and the specific changes development teams need to make.

The OWASP Top 10 2026 edition brings the most significant structural change since the 2021 update: Software Supply Chain Failures debuts at A03, replacing the narrower “Vulnerable and Outdated Components” category that occupied that position. The expansion acknowledges that supply chain risk in 2026 extends well beyond running a library with a known CVE — it encompasses compromised build pipelines, malicious packages, typosquatting, dependency confusion, and the whole attack surface created by the software you don’t write yourself. CI/CD pipeline attacks are up 45% since 2022; 50% of OWASP survey respondents ranked supply chain failures as the single highest risk. A03 is the right placement.

What Changed From A06:2021 to A03:2026

The 2021 category (“A06: Vulnerable and Outdated Components”) was essentially about dependency hygiene — keeping your libraries patched. The 2026 A03 category covers the full attack surface:

  • Compromised upstream packages: malicious code injected into legitimate packages (SolarWinds model applied to open source)
  • Dependency confusion attacks: internal package names resolved to attacker-controlled public registry packages
  • Typosquatting: reqeusts instead of requests, crypt0 instead of crypto
  • Malicious CI/CD actions: GitHub Actions, Jenkins plugins, and build tools with supply chain compromise
  • Build system compromise: attacks that inject malicious code at build time rather than in source
  • AI-hallucinated packages (slopsquatting): LLMs recommending non-existent packages that attackers then register

Practical Changes for Development Teams

1. Lock Your Dependency Trees

Using unpinned dependencies (requests>=2.28) means your build is resolved at install time against whatever is currently available on the registry. An attacker who compromises a package or publishes a higher-version malicious package gets into your next build.

Python — use hashed requirements:

pip-compile --generate-hashes requirements.in > requirements.txt

The resulting requirements.txt:

requests==2.32.3 \
    --hash=sha256:58cd2187423d... \
    --hash=sha256:a9234fb27... 

Installing with pip install --require-hashes -r requirements.txt fails if the downloaded package doesn’t match the recorded hash.

Node.js — use lockfiles and verify:

# Generate lockfile
npm install
# Install from lockfile only (fails on lockfile mismatch)
npm ci
# Verify integrity of installed packages
npm audit signatures

Go — module verification is on by default:

// go.sum records cryptographic hashes — committed to version control
// GONOSUMCHECK and GONOSUMDB env vars should never be set in production builds
// Verify no tampering:
go mod verify

2. Implement SBOM Generation in CI

A Software Bill of Materials (SBOM) records every component in your software, including transitive dependencies. As of 2026, SBOM generation is moving from advisory guidance to contractual requirement in EU-regulated supplier contracts and US federal procurement.

Generate SBOM in GitHub Actions:

# .github/workflows/sbom.yml
name: SBOM Generation
on: [push, pull_request]
jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Generate SBOM (Syft)
        uses: anchore/sbom-action@v0
        with:
          format: cyclonedx-json
          output-file: sbom.json
      - name: Upload SBOM artifact
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.json
# Local SBOM generation with Syft
syft dir:. -o cyclonedx-json > sbom.json

# Vulnerability scan against SBOM
grype sbom:sbom.json

3. Harden Your CI/CD Pipeline

The A03 elevation reflects that attackers are targeting build pipelines, not just runtime dependencies. GitHub Actions workflow compromise, malicious Jenkins plugins, and supply chain attacks on CI dependencies are documented attack patterns.

Pin GitHub Actions to commit SHA, not a tag:

# INSECURE — tag can be moved to point to malicious code
- uses: actions/checkout@v4

# SECURE — commit SHA cannot be moved
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

Restrict what CI can access using OIDC instead of long-lived secrets:

# AWS OIDC — no static credentials stored in GitHub
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/github-actions-role
    aws-region: us-east-1
    # No access-key-id or secret-access-key — token is issued via OIDC

Add a dependency review step to catch new vulnerable packages:

- name: Dependency Review
  uses: actions/dependency-review-action@v4
  with:
    fail-on-severity: high
    deny-licenses: GPL-3.0, AGPL-3.0  # Optional licence policy

4. Verify Packages Before Install

For Python and npm, verify the publisher’s identity before installing packages that aren’t from well-known maintainers.

npm — check for legitimate publisher identity:

# Check package provenance (requires npm 9+)
npm audit signatures <package-name>

# Check who published a package
npm view <package-name> maintainers

PyPI — use Trusted Publishers (OIDC) for packages you publish:

# pyproject.toml — configure trusted publishing
[tool.poetry]
name = "mypackage"
# Trusted publisher configuration is done in PyPI project settings
# not in pyproject.toml itself, but include provenance in CI

Implement a private registry proxy for internal packages:

In environments vulnerable to dependency confusion attacks (where internal package names match what an attacker could publish to PyPI or npm), route all package installs through a proxy that enforces an allowlist:

# npm: configure Verdaccio or Artifactory as upstream proxy
npm config set registry https://your-private-registry.example.com

# pip: configure devpi or Artifactory
pip config set global.index-url https://your-private-registry.example.com/simple/

5. AI-Generated Code Review Checklist

With LLM code generation producing supply chain risks through hallucinated package recommendations, add a supply chain check to your AI code review process:

  • Does the AI-generated code reference any packages you haven’t used before?
  • Do those packages actually exist on the registry? (Verify with npm view <pkg> or pip show <pkg>)
  • Are they maintained by who you’d expect?
  • Was the package name close to a well-known package (typosquatting risk)?
# Example: AI suggested "reqests" instead of "requests" — classic typosquatting target
# Always verify unfamiliar package names before import
import subprocess
result = subprocess.run(['pip', 'show', 'reqests'], capture_output=True, text=True)
if not result.stdout:
    raise ValueError("Package not found — possible typosquatting risk")

The SLSA Framework

Supply-chain Levels for Software Artifacts (SLSA) provides a graduated assurance framework for supply chain integrity. In 2026, SLSA Level 2 (build integrity tracked by a build service, with provenance) is the realistic baseline for production software. SLSA Level 3 (hardened build service with non-falsifiable provenance) is required for high-assurance targets.

The OWASP A03:2026 elevation effectively signals that “you should have a dependency scanner running” is no longer sufficient. Supply chain security in 2026 requires pinned dependencies, SBOM generation, CI/CD hardening, and package provenance verification. The attack surface grew; the controls need to keep pace.