12 Punkte von darjeeling 2026-03-13 | Noch keine Kommentare. | Auf WhatsApp teilen

Kernzusammenfassung
Um auf Supply-Chain-Angriffe gegen das Python-Paket-Ökosystem zu reagieren, ist eine mehrschichtige Verteidigungsstrategie erforderlich, die sich nicht auf eine einzelne Kontrolle verlässt. Der Beitrag empfiehlt, statische Schwachstellen mit den S-(Bandit)-Regeln von Ruff zu blockieren, Abhängigkeiten mit uv über kryptografische Hashes festzuschreiben und in CI-Umgebungen pip-audit sowie die Erstellung einer SBOM (CycloneDX) einzusetzen. Für die Paketveröffentlichung wird die Einführung von OIDC-basiertem Trusted Publishing anstelle langlebiger API-Tokens empfohlen. Zudem wird eine praxisnahe Pipeline vorgestellt, bei der die Einführung neuer Pakete absichtlich verzögert wird (Delayed Ingestion), um der Community Zeit zur Prüfung potenziell bösartiger Pakete zu geben.

Detaillierte Analyse

  • Angriffsvektoren in der Lieferkette und transitive Abhängigkeiten (Transitive Dependencies): Auf PyPI gibt es inzwischen mehr als 740.000 Pakete, und schwerwiegende Sicherheitsvorfälle wie die Übernahme der ctx-Domain, die Injektion in CI-Skripte von Ultralytics (YOLO) und der Token-Diebstahl bei GhostAction treten weiterhin auf. Selbst wenn nur ein einzelnes Paket wie Flask installiert wird, werden zahlreiche transitive Abhängigkeiten wie MarkupSafe mitinstalliert. Dadurch werden auch Pakete, die Entwickler nicht explizit deklariert haben, zu einer großen Angriffsfläche (Attack Surface).
  • Frühzeitiges Blockieren von Schwachstellen im eigenen Code: Noch vor externen Paketen müssen Fehler im internen Code verhindert werden. Hartkodierte Secrets, schwache Hash-Algorithmen (MD5, SHA1), Netzwerkaufrufe ohne Timeout (DoS-Risiko) und unsichere Serialisierung (pickle) werden im Code-Review leicht übersehen. Um das zu verhindern, ist es essenziell, die Bandit-Sicherheitsregeln von Ruff in CI/CD-Pipelines und IDEs zu integrieren, damit solche Probleme automatisch erkannt und blockiert werden.
  • Festschreiben von Abhängigkeiten und verzögerte Einführung (Delayed Ingestion): Bei der Installation von Abhängigkeiten reicht es nicht, nur Versionen anzugeben. Zusätzlich sollten kryptografische Hashes der Pakete festgeschrieben werden, um Manipulationen in der Laufzeitumgebung zu verhindern. Um außerdem das Risiko frisch veröffentlichter bösartiger Pakete zu reduzieren, bis diese erkannt und blockiert werden, ist es sinnvoll, das Flag --exclude-newer von uv zu nutzen oder in einem internen Mirror-Repository eine „7-Tage-Ingestion-Queue“ einzurichten, sodass nur Pakete nach einer ersten Community-Prüfung ins interne Netzwerk gelangen.
  • Sichere Paketveröffentlichung: Open-Source-Maintainer und Paket-Publisher sollten statische API-Tokens, die dauerhaft dem Risiko einer Kompromittierung ausgesetzt sind, abschaffen und auf OIDC-basiertes Trusted Publishing mit Sigstore umsteigen. Dadurch werden automatisch Attestations erzeugt, die die Verbindung zum Source-Repository kryptografisch nachweisen.

Wichtige Codes und Daten

1. Transitive Abhängigkeiten (Transitive Dependencies) prüfen

# Unsichtbaren Abhängigkeitsbaum prüfen, der bei der Installation eines einzelnen Pakets (Flask) mitkommt  
uv pip install flask  
uv pip tree  
  
# Output:  
flask v3.1.0  
├── blinker v1.9.0  
├── click v8.1.8  
├── itsdangerous v2.2.0  
├── jinja2 v3.1.5  
│   └── markupsafe v3.0.2  
└── werkzeug v3.1.3  
    └── markupsafe v3.0.2  
  
2. Anwendung des Sicherheitsregelsatzes (Bandit) mit Ruff  
# Beispiel für eine `pyproject.toml`-Konfiguration  
[tool.ruff]  
line-length = 120  
# S (Bandit-Sicherheitsregeln) zusammen mit E (Error) und F (Pyflakes) aktivieren  
lint.select = ["E", "F", "S"]  
  
# Beispiele typischer Schwachstellenmuster, die vom Ruff-Regelsatz 'S' automatisch erkannt werden  
# FLAGGED: S301 - `pickle.loads()` birgt das Risiko beliebiger Codeausführung (`json.loads()` empfohlen)  
import pickle  
data = pickle.loads(untrusted_input)  
  
# FLAGGED: S608 - SQL-Injection-Schwachstelle durch String-Formatting  
cursor.execute(f"SELECT * FROM users WHERE name = '{user_input}'")  
  
# FLAGGED: S113 - Externe Anfrage ohne gesetzten Timeout (unendliches Warten und DoS-Angriffsfläche)  
import requests  
response = requests.get("[https://api.example.com/data](https://api.example.com/data)")  
  
3. Kontrolle neuer Pakete durch verzögerte Einführung (Delayed Ingestion)  
# Nur Pakete als Abhängigkeiten kompilieren, die vor einem bestimmten Datum (z. B. vor 7 Tagen) veröffentlicht wurden, um frühe Malware/Fehler zu vermeiden  
uv pip compile --exclude-newer 2026-03-02 requirements.in -o requirements.txt  
  
4. Pipeline zur Ingestion-Kontrolle innerhalb der Organisation  
| Verarbeitungsschritt | Systemkomponente | Sicherheitsziel und Beschreibung |  
|---|---|---|  
| Eingang | PyPI ➜ Ingestion Queue | Neu in PyPI registrierte Pakete werden nicht sofort im internen System verteilt, sondern zunächst in eine Warteschlange aufgenommen |  
| Warten | Wait (z. B. 7 Tage) | Gewinnt der Community und Sicherheitsforschern die notwendige Zeit, um Bösartigkeit und Schwachstellen des Pakets zu analysieren |  
| Prüfung | Security Scan ➜ Approved | Nach Ablauf der Wartezeit wird ein Paket nur dann freigegeben, wenn es Scans auf bekannte Schwachstellen (CVE) und Malware besteht |  
| Verteilung | Internal Mirror ➜ Developers | Nur verifizierte Pakete werden im internen Mirror-Repository gecacht und den Entwicklungsteams zur sicheren Nutzung bereitgestellt |

Noch keine Kommentare.

Noch keine Kommentare.