Supply Chain Angriff - Software-Lieferkette als Angriffsvektor
Supply chain attacks compromise software or hardware before it reaches its destination: SolarWinds (18,000 victims, SUNBURST backdoor), XZ Utils backdoor (CVE-2024-3094), npm typosquatting, dependency confusion, malicious NPM packages, CI/CD pipeline compromise. Protection: SBOM (CycloneDX/SPDX), SLSA Framework, Sigstore/Cosign for package signing, private registry, dependency pinning.
Supply chain attacks do not compromise the target directly, but rather a trusted supplier or a dependency. The victim installs the compromised software themselves—and trusts it completely.
The Supply Chain Concept
Why the Supply Chain Is So Effective
In a direct attack, the attacker must overcome many security barriers: firewalls, EDR, and MFA stand between them and the target.
In a supply chain attack, however, the path to the target is elegantly simple: attacker → supplier/package → target trusts update → backdoor.
The advantages for attackers are significant:
- Signed code: EDR detection is bypassed because a legitimate certificate is present
- Wide reach: A compromised supplier affects thousands of victims simultaneously
- Exploiting trust: "We always install the update" – security teams rarely check trusted updates
- Persistence: The update arrives as part of normal business operations and goes unnoticed
Known Attack Vectors
- Software updates (SolarWinds, 3CX)
- Open-source packages (NPM, PyPI, RubyGems)
- CI/CD pipelines (compromised build servers)
- Container images (DockerHub, Harbor)
- Hardware (tampered chips/network devices)
- Managed Service Providers (MSP → customers)
SolarWinds - The Master Case
Timeline
| Date | Event |
|---|---|
| October 2019 | Attackers infiltrate the SolarWinds network |
| March 2020 | SUNBURST backdoor embedded in Orion 2019.4.5280.20438 |
| March 2020 | Signed update distributed to ~18,000 customers |
| December 2020 | FireEye discovers the attack, public disclosure |
SUNBURST Mechanism
The backdoor was embedded in SolarWinds.Orion.Core.BusinessLayer.dll. After installation, it remained dormant for 12–14 days to evade sandbox detection systems. C2 communication occurred via DNS queries with encrypted beacons to domains generated by a Domain Generation Algorithm (DGA) – based on avsvmcloud.com. The backdoor only activated when no analysis tools such as Wireshark or IDA were detected running.
Victims
Those affected included the U.S. Department of the Treasury, DHS, the Department of Justice, and the NSA, as well as Microsoft, Intel, Cisco, and FireEye. In total, over 100 U.S. federal agencies were affected, and the attackers had nearly complete access for about 9 months.
Lessons from SolarWinds
- Code signing is no guarantee of security – the certificate was entirely legitimate
- Build environments are a target – not just the code itself
- DNS monitoring is essential – even for trusted IT tools
XZ Utils Backdoor (2024)
What would have happened
XZ Utils is a compression library found in nearly every Linux distribution. The planned backdoor would have compromised SSH authentication on all affected systems. With an embedded Ed448 key, the attacker would have had unlimited root access to millions of servers worldwide.
The Social Engineering Phase (2 Years)
Starting in 2022, an account named "Jia Tan" began making regular contributions to XZ Utils on GitHub and built trust over the course of a year until becoming a co-maintainer. In 2024, under false pretenses—a staged "maintainer burnout" scenario—the handover of control was offered. After commit access was obtained, the backdoor was built into Release 5.6.0 in February 2024.
Backdoor Technique
The backdoor was contained exclusively in the binary tarball, not in the Git repository itself. Test files (tests/*.xz) contained encrypted backdoor code, which was extracted and compiled by the CMake build system. The code loaded into the systemd-sshd process and replaced the RSA key decryption function to enable command injection.
Discovery by Chance
Andres Freund (Microsoft) noticed that SSH logins on Debian unstable were 500 milliseconds slower than expected. CPU profiling led him to xz-utils. He reported the finding on March 29, 2024.
Mitigation Measures
- Binary Transparency: Verify build reproducibility
- Reproducible Builds: Identical source code should produce a bit-for-bit identical binary
- SBOM Monitoring: When did a dependency change?
NPM/PyPI Package Attacks
1. Typosquatting
Attackers register packages with names very similar to legitimate ones:
| Legitimate | Malicious |
|---|---|
lodash | 1odash (digit instead of l) |
lodash | lodas |
lodash | lodash-utils |
Known Cases:
event-stream(2018): 2 million downloads/week; target was Bitcoin wallet theftua-parser-js(2021): 7 million downloads/week compromisednode-ipc(2022): Maintainer inserted wiper code as a political statement
2. Dependency Confusion
# Internal package: "@company/internal-utils" v1.0.0 (private)
# Attacker: "@company/internal-utils" v9.0.0 (public → higher version!)
# npm install → installs v9.0.0 from public NPM!
This attack has been demonstrated at Apple, Microsoft, PayPal, Tesla, and Shopify. Bug bounty payouts reached up to $30,000.
3. Account Takeover (Maintainer Takeover)
Attackers gain access to the maintainer’s account via credential stuffing using leaked passwords or by compromising the maintainer’s PC and exfiltrating tokens. They then publish a malicious update.
Scanning Tools
# npm-audit (built-in):
npm audit --production
# OWASP Dependency Check:
dependency-check.sh --scan ./node_modules --format HTML
# Socket.dev (real-time package intelligence):
npx @socketsecurity/cli scan
# Snyk Open Source:
snyk test --all-projects
CI/CD Pipeline Compromise
Attack Vectors
Secrets in Pipeline Configurations: Incorrectly configured secrets may be readable in build logs.
Poisoned Pipeline Execution (PPE): A fork of the repo triggers a CI pipeline with write access via a pull request. Attackers modify env.yml, Jenkinsfile, or .github/workflows/ files.
Dependency in the Build Process: Attackers compromise a build tool (Make, Gradle plugin, Maven plugin).
GitHub Actions Security
# WRONG - no pinned version:
uses: actions/checkout@main
# CORRECT - pinned to commit SHA:
uses: actions/checkout@v4.2.2
# Or via SHA:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
# OIDC instead of long-lived secrets:
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: eu-central-1
# → No AWS_SECRET_ACCESS_KEY in the repository!
# Step Summary instead of echo output (prevents log injection):
echo "Deploy complete" >> $GITHUB_STEP_SUMMARY
SBOM and SLSA Framework
Software Bill of Materials (SBOM)
An SBOM is a machine-readable bill of materials for all software components. The common formats are CycloneDX (OWASP, JSON/XML) and SPDX (Linux Foundation).
# Syft (Anchore, free):
syft packages dir:. -o cyclonedx-json > sbom.json
# CycloneDX for NPM:
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --output-file sbom.json
# GitHub Actions Integration:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom.spdx.json
format: spdx-json
Benefits of SBOM: With Log4Shell, it was immediately clear whether log4j was present in the stack. With XZ Utils, all affected systems could be identified immediately. In M&A, the SBOM enables comprehensive due diligence regarding licensing risks and vulnerabilities.
SLSA Framework (Supply-chain Levels for Software Artifacts)
| Level | Description |
|---|---|
| Level 1 | Documented build process, build logs available, SBOM generated |
| Level 2 | Build service and version control: signed provenance, authenticated build service |
| Level 3 | Hardened build process: no network access during build, ephemeral build environment |
| Level 4 | Reproducible builds (highest security): bit-identical binary for the same source code |
# SLSA GitHub Actions:
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
Protective Measures
1. Dependency Pinning and Lock Files
# NPM - Never ignore package-lock.json:
npm ci # instead of npm install (uses lock file!)
# Python - requirements.txt with exact versions:
requests==2.31.0
# pip-compile (pip-tools) for reproducible environments:
pip-compile requirements.in
// Renovate configuration for automatic update PRs:
{
"extends": ["config:base"],
"vulnerabilityAlerts": {"enabled": true},
"schedule": ["before 5am on monday"]
}
2. Dependency Confusion Protection
# .npmrc - always use internal packages from your own registry:
@company:registry=https://registry.company.internal
# Or: register scoped packages on a private registry
3. Sigstore/Cosign - Container Image Signing
# Sign image:
cosign sign --key cosign.key ghcr.io/company/app:v1.0.0
# Verify signature:
cosign verify --key cosign.pub ghcr.io/company/app:v1.0.0
# Kubernetes Policy (Kyverno): automatically rejects unsigned images
4. Private Registry and Allowlisting
Use Nexus or JFrog Artifactory as a proxy: All downloads go through your own registry; known packages are cached and scanned; new packages go through a manual approval process.
5. Monitoring and Alerting
# GitHub Dependency Review Action:
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate
deny-licenses: GPL-2.0, AGPL-3.0
If a dependency changes, an alert should be triggered immediately.