15 Punkte von GN⁺ 2025-11-22 | 3 Kommentare | Auf WhatsApp teilen
  • Dependency-Cooldowns sind eine einfache und wirksame Sicherheitstechnik, mit der sich die meisten Angriffe auf die Open-Source-Lieferkette abmildern lassen
  • Angreifer kapern in der Regel beliebte Open-Source-Projekte und verteilen darüber Schadcode, doch bei den meisten Angriffen ist das Zeitfenster der Exponierung kürzer als eine Woche
  • Wenn nach der Veröffentlichung einer neuen Version ein Cooldown mit einer Wartezeit (z. B. 7 Tage) festgelegt wird, lässt sich das Infektionsrisiko durch automatische Updates deutlich senken
  • Dependabot, Renovate, pnpm usw. unterstützen Cooldowns bereits standardmäßig, die Einrichtung ist einfach und verursacht keine zusätzlichen Kosten
  • Wenn Cooldowns auf Ebene des Paketmanagers standardmäßig bereitgestellt werden, kann das die Sicherheit der Lieferkette stärken und unnötige Warnmeldungen reduzieren

Struktur und Probleme von Lieferkettenangriffen

  • Die meisten Lieferkettenangriffe (supply chain attacks) folgen demselben Muster
    • Angreifer verschaffen sich Zugang über gestohlene Zugangsdaten eines beliebten Open-Source-Projekts oder über CI/CD-Schwachstellen
    • Sie laden bösartige Änderungen in Distributionskanäle wie PyPI oder npm hoch
    • Durch automatische Updates oder fehlende Versionsfixierung installieren Nutzer die infizierte Version
    • Sicherheitsanbieter erkennen dies, warnen davor, und das Paket-Repository entfernt die betroffene Version
  • Der Abstand zwischen den Schritten (1) und (2) ist lang, aber die Schritte (2) bis (5) werden innerhalb von Stunden bis wenigen Tagen abgewickelt, sodass das aktive Zeitfenster der Angreifer kurz ist
  • Zeitfenster der Angriffsmöglichkeit (window of opportunity) in wichtigen Fällen der letzten 18 Monate
    • xz-utils: etwa 5 Wochen
    • Ultralytics: 12 Stunden (Phase 1), 1 Stunde (Phase 2)
    • tj-actions: 3 Tage
    • chalk: weniger als 12 Stunden
    • Nx: 4 Stunden
    • rspack: 1 Stunde
    • num2words: weniger als 12 Stunden
    • Kong Ingress Controller: etwa 10 Tage
    • web3.js: 5 Stunden
  • 8 dieser Fälle hatten ein Angriffsfenster von weniger als einer Woche und wären größtenteils durch Cooldowns blockiert worden

Konzept und Wirkung von Cooldowns

  • Ein Cooldown verzögert die Nutzung neuer Abhängigkeiten für einen bestimmten Zeitraum nach ihrer Veröffentlichung
    • In dieser Zeit können Sicherheitsanbieter erkennen, ob eine Version bösartig ist
  • Vorteile
    • Nachweislich wirksam und in der Lage, die meisten groß angelegten Angriffe zu blockieren
    • Sehr einfach umzusetzen und in den meisten Tools kostenlos konfigurierbar
    • Dependabot-Beispiel
      version: 2
      - package-ecosystem: github-actions
        directory: /
        schedule:
          interval: weekly
        cooldown:
          default-days: 7
      
    • Fördert positives Verhalten bei Sicherheitsanbietern: Statt übermäßiger Warnungen oder PR konzentrieren sie sich auf schnelle Erkennung

Fazit und Empfehlungen

  • Bei 8 von 10 Angriffen lag das Angriffsfenster bei höchstens einer Woche, und mit einem 7-Tage-Cooldown ließe sich der Großteil blockieren
  • Mit einem 14-Tage-Cooldown wären alle Fälle außer xz-utils abgedeckt
  • Cooldowns sind keine perfekte Lösung, aber eine einfache Methode, das Expositionsrisiko um 80–90 % zu senken
  • Neben Dependabot und Renovate sollten auch Paketmanager selbst Cooldowns standardmäßig unterstützen
  • Sicherheit in der Lieferkette ist nicht nur ein technisches Problem, sondern auch eine Frage sozialer Vertrauensstrukturen – Cooldowns sind dabei jedoch eine nützliche, realistische Gegenmaßnahme

3 Kommentare

 
regentag 2025-11-23

Eigentlich scheint es besser zu sein, gar nicht erst zu aktualisieren, wenn es kein Problem gibt.
Sollte man wirklich unbedingt eine neue Version einspielen, die sich kaum von der vorherigen unterscheidet, und dafür das Risiko in Kauf nehmen?

 
GN⁺ 2025-11-22
Hacker-News-Kommentar
  • Menschen sorgen sich, dass sie ohne sofortige Updates schweren Schwachstellen ausgesetzt sind, aber in der Praxis ist das meist nicht der Fall
    Viele Softwareprodukte werden nicht per Continuous Deployment ausgeliefert, sondern Kunden installieren neue Versionen selbst, daher erfolgen Updates oft nur im Abstand von Wochen oder Monaten
    Entscheidend sind Dependency-Monitoring und die Prüfung veröffentlichter Schwachstellen. Man bewertet zunächst, ob das Produkt tatsächlich betroffen ist, und aktualisiert diese Dependency dann nur in diesem Fall sofort

    • Im gesamten Ökosystem fehlt eine solche Kultur der selektiven Updates
      Es ist die Vorstellung verbreitet, dass man bei jeder neuen Version heute noch aktualisieren müsse
      Änderungen nicht wirklich zu prüfen und stattdessen nach dem Motto „Später wird es noch schwerer, also machen wir es jetzt“ vorzugehen, ist ineffizient
      An der vordersten Front der Versionsnummern zu bleiben, kann der Sicherheit sogar abträglich sein
    • Das praktische Problem ist, dass viele Security-Teams großer Unternehmen eine „zero CVE“-Politik erzwingen
      In unserem Unternehmen muss innerhalb von 7 Tagen aktualisiert werden, wenn ein Scanner eine kritische Schwachstelle findet
      Wird die Frist überschritten, beginnt wegen eines Compliance-Verstoßes ein komplizierter Prozess, daher aktualisieren die meisten einfach alles sofort
    • Menschen fürchten 0-days, aber die meisten realen Probleme entstehen durch Schwachstellen, die über Hunderte Tage ungepatcht bleiben
    • Entscheidend ist, ob eine App unbekannte Eingaben von außen annimmt
      Anwendungen wie Browser mit viel externem Input sollten häufig aktualisiert werden, während etwa eine Wetter-App mit begrenztem Input vergleichsweise sicher ist
    • Die Strategie „nur bei Bedarf updaten“ klingt theoretisch gut, aber in der Praxis sind die Kosten zu hoch, jede Schwachstelle produktbezogen zu bewerten
      Effizienter ist es, regelmäßig zu aktualisieren und gleichzeitig Schutzmaßnahmen gegen Supply-Chain-Angriffe umzusetzen
  • Ein Modell wie Debian stable, bei dem die Distribution gemeinsame Dependencies verwaltet und alle paar Jahre ein Gesamt-Upgrade durchführt, wirkt zunehmend vernünftig
    Manche Ökosysteme bewegen sich zu schnell, oder ihre distributionsspezifischen Paketierungssysteme sind zu schwach
    Zum Beispiel ist es immer noch schwierig, Node.js-Bibliotheken per apt zu installieren und im Projekt zu verwenden

    • Man sollte „Bewegung“ nicht mit „Handeln“ verwechseln
      Ein Ökosystem, das sich schnell bewegt, ohne grundlegende Veränderungen hervorzubringen, ist nicht gesund
      JS hat in den letzten 3 Jahren kaum echten Fortschritt gemacht, aber wenn man ein 3 Jahre altes Projekt erneut bauen will, bedeutet das Leid auf Rewrite-Niveau
    • Die Suchergebnisse für Debian-Node-Pakete zeigen, dass es einige gibt, aber nicht vollständig
      In Distributionen wie Arch gibt es sie teils gar nicht
    • Mit Rust kann man allein auf Basis des Debian-Repositorys ausreichend arbeiten
    • Das Stable-Release-Modell bringt die Last mit sich, dass Apps gleichzeitig alte und neue Versionen unterstützen müssen
  • Es gibt die Annahme, dass eine Cooldown-Phase bei Dependency-Updates zur Abwehr von Supply-Chain-Angriffen besser ist, als sofort die neueste Version zu verwenden, um 0-days zu stoppen
    Es geht um den Vergleich zwischen der Wahrscheinlichkeit, dass ein Update eine neue Schwachstelle einführt, und der Wahrscheinlichkeit, dass es eine bestehende behebt
    Nach SemVer sind Patch-Versionen relativ sicher, daher ist auch ein Ansatz mit kurzer Cooldown-Phase denkbar
    Wenn zum Beispiel auf 2.3.4 die Version 2.4.0 erscheint, ist es ohne dringenden Funktionsbedarf womöglich besser, bis 2.4.1 zu warten

    • Bei veröffentlichten 0-days gibt es Security Advisories, daher patchen Tools wie Dependabot trotz Cooldown sofort
      Die meisten Schwachstellen entstehen nicht durch absichtliche Angriffe, sondern durch gewöhnliche Bugs
    • Voreinstellungen beruhen immer auf Annahmen. Wenn neue Informationen auftauchen, kann man sie ändern
  • Eine Politik, die Anzahl und Komplexität von Dependencies begrenzt, ist ein stärkerer Ansatz
    Statt „Bibliotheken, die alles machen“, sollte man nur kleine Dependencies mit klarem Zweck hinzufügen
    Außerdem wäre die Verwaltung einfacher, wenn Bibliotheken LTS-Versionen anbieten würden, die nur Security-Patches enthalten

    • Solche Argumente hört man oft, aber in der Praxis ist die Wiederverwendung validierten Codes deutlich effizienter
      Es selbst noch einmal zu implementieren, kann Verschwendung sein. Ich würde gern ein konkretes Beispiel für eine problematische „everything library“ sehen
    • Die meisten Supply-Chain-Angriffe entstehen über die sozialtechnische Angriffsfläche
      Wenn man demselben Entwickler über mehrere Bibliotheken hinweg vertraut, sind Vertrauensbeziehungen wichtiger als die Zahl der Pakete
      Komplexität korreliert zwar mit Schwachstellen, ist aber nicht deren direkte Ursache
    • Durch das Aufkommen von AI-Tools sinken die Kosten, nicht zentrale Dependencies selbst zu implementieren
      Damit werden Entscheidungen möglich, die statt auf kurzfristige Geschwindigkeit stärker auf langfristige Wartbarkeit zielen
    • Zu stark fragmentierte Dependencies können im Gegenteil ihre Zahl und den Build-Aufwand erhöhen
    • Dass Low-Level-Bibliotheken selbst weitere Dependencies haben, lässt sich nur schwer rechtfertigen
      In der C++-Welt ist das mitunter sogar ein Wettbewerbsfaktor
  • Der Druck, immer auf die neueste Version zu aktualisieren, beruht auf dem falschen Glauben, dass Software ständig besser wird
    In Wirklichkeit tauscht man damit womöglich bekannte Bugs gegen neue unbekannte Bugs aus
    Veröffentlichte Issues zu beobachten und nur bei Bedarf zu patchen, ist vernünftig

    • Beim Beispiel log4shell war log4j 1.x etwa nicht betroffen, und der Bug wurde erst in 2.x eingeführt
      Das ist also ein Fall, in dem die ältere Version sogar sicherer war
    • Früher waren die Abstände zwischen Releases länger, sodass Qualitätsverbesserungen deutlicher ausfielen, heute handelt es sich meist nur noch um Änderungen an der Peripherie
      Vielleicht liegt das auch daran, dass wir bereits ausreichend stabile Software verwenden
  • Wenn alle sagen „Warten wir ein wenig“, überprüft am Ende wie bei einer Tragik der Allmende niemand mehr zuerst
    Je länger man wartet, desto mehr technische Schulden häufen sich an, daher braucht es inkrementelle Updates und Gegenmaßnahmen wie Zero Trust und Monitoring

    • Nach einer neuen Version etwa eine Woche zu warten ist keine große technische Schuld
      In dieser Zeit haben Security-Scanner Schwachstellen meist bereits erkannt
    • Jüngste Supply-Chain-Angriffe wurden nicht durch Exposition bei Konsumenten entdeckt, sondern dadurch, dass Maintainer Zeit zur Reaktion hatten
    • Selbst wenn die Zahl der Nutzer sinkt, gewinnen Forschende und Maintainer Zeit für Analysen
      Wenn ein Angreifer einen unautorisierten Release hochlädt, wird das manchmal sofort bemerkt
    • Große Systeme machen ohnehin schrittweise Rollouts, daher ist ein sofortiges Gesamt-Update ohnehin unmöglich
  • Die Cooldown-Idee ist gut, aber es besteht das Risiko, dass Angreifer sie missbrauchen und künstliche Dringlichkeit erzeugen
    Unter dem Vorwand eines „dringenden Security-Patches“ könnten sie zu früher Installation verleiten, obwohl diese Version in Wahrheit bösartig ist
    Gegen solche Angriffe mit psychologischem Druck muss man gewappnet sein

    • Wenn ein Angreifer beim Verteilen eines Exploits gleichzeitig einen Bugfix mitliefert, kann er Entwickler dazu verleiten, die Cooldown-Regel zu brechen und sofort zu installieren
    • Es taucht die Frage auf: „Wie würde man so ein Rauschen überhaupt erzeugen?“ — also Zweifel daran, wie Angreifer die öffentliche Wahrnehmung manipulieren könnten
  • Ein weiterer Grund für Cooldown ist, Maintainern Zeit zu geben, einen eigenen Kompromittierungsfall zu bemerken
    Angreifer zielen auf Zeitpunkte, an denen Maintainer nicht verfügbar sind, etwa Urlaub, Konferenzen oder Feiertage
    Viele Projekte werden von ein oder zwei Personen betreut, daher ist ein solcher Zeitversatz sehr wichtig

  • Es hängt von den Eigenschaften des Projekts und seiner Angriffsfläche ab
    Die Zeit, in der man einfach nur „Best Practices“ folgt, sollte vorbei sein
    Security ist wie ein Kontaktsport: Man muss täglich kritisch über Details nachdenken

  • Es gibt auch Grenzen des Cooldowns als Annahme, dass etwas allein durch Zeit sicherer wird
    Wenn niemand den Code anschaut, bleibt er auch nach einer Woche genauso riskant
    Stattdessen kann ein Ansatz mit gradual rollout wirksam sein
    Jeder Verbraucher setzt dabei einen Verzögerungsfaktor, sodass risikobereitere Seiten zuerst auf Probleme stoßen,
    während die übrigen in der Zwischenzeit geschützt sind
    Riskante Updates werden aus der Queue entfernt, sodass verzögerte Verbraucher sie gar nicht erst zu sehen bekommen

 
aer0700 2025-11-23

In letzter Zeit bin ich manchmal unsicher, was besser zu verkraften ist: einfach das Rad neu zu erfinden oder den Aufwand, Abhängigkeits-Tetris zu verwalten.
Wenn bei Ersterem etwas schiefläuft, kann ich einfach meinen eigenen Code korrigieren, aber beim Abhängigkeits-Tetris ist es viel schwerer zu debuggen, wenn plötzlich irgendwo ein Rad eiert.