Anastasiia - stock.adobe.com

Die Lieferketten von Software wirksam abhärten

Software wird immer komplexer. Das trifft auch auf die Lieferketten zu. Die verwobenen Herstellprozesse bedeuten dabei mehr potenzielle Angriffsvektoren für Bedrohungsakteure.

So kann eine einzelne kompromittierte Stelle – und sei es auch nur eine kleine Softwarebibliothek in einem Netz von Abhängigkeiten – zu immensem Schaden führen. Wie lassen sich also in heutigen Zeiten die Supply Chains abhärten? Der Schlüssel liegt in umfassender Dokumentation und Bewertung über die Lieferkette hinweg.

Angriffe auf Supply Chains sind mittlerweile keine Seltenheit mehr und kommen in den unterschiedlichsten Formen vor. So verbreitete sich die Malware Keyzetsu unter anderem über kompromittierte Plug-Ins für die Entwicklungsumgebung Visual Studio Code. Weithin bekannt wurde zudem der Social-Engineering-Angriff auf die beliebte XZ-Bibliothek, die zu einer potenziellen Backdoor in SSH führte. Auch die Log4Shell getaufte Schwachstelle in der Java Log4J-Bibliothek verursachte schwere Schockwellen.

Solche Supply-Chain-Attacken sind insbesondere gefährlich, weil eine infizierte Stelle ausreicht, um unter Umständen alle davon abhängigen Prozesse und Lösungen zu kompromittieren. Der Gesetzgeber hat dementsprechend die Gefahr erkannt und legt mit Rahmenwerken wie NIS2, DORA sowie CRA (Cyber Resilience Act) scharfe Anforderungen bezüglich Dokumentation und Bewertung an die Beteiligten der Software Supply Chain fest.

Was sind die konkreten Schwachstellen der Softwarelieferkette?

Angriffsvektoren auf Supply Chains gibt es dabei viele. Das liegt daran, dass heute kaum noch eine Software vollständig von einem Unternehmen oder einem Programmierer allein entwickelt wird. Oftmals herrscht ein komplexes Geflecht von Abhängigkeiten verschiedener externer Bibliotheken vor. Die Definition und das Update von Abhängigkeiten werden dabei zwar durch moderne Paketmanager erheblich erleichtert, was die Sache jedoch gleichzeitig erschwert: durch die Abhängigkeit zu einer Bibliothek entstehen auch transiente Abhängigkeiten, die in der Regel unbeachtet bleiben. Jede dieser Abhängigkeiten ist wiederum ein potenzielles Sicherheitsrisiko.

Diese Problematik ist durchaus bekannt und mittlerweile gibt es einige ausgereifte Maßnahmen zur Dokumentation und Verwaltung von komplexen Abhängigkeitsstrukturen in Form von SBOMs (Software Bills of Material). Die SBOMs werden dabei von Werkzeugen entweder während des Build-Prozesses oder aus Softwareartefakten generiert. Management-Plattformen wiederum speichern die SBOMs für Produkte in verschiedenen Versionen und prüfen diese kontinuierlich auf Sicherheitslücken. Solche automatisierten Lösungen sind dabei als Cloud-Service oder On-Premises erhältlich (zum Beispiel DependencyTrack). Die Aufgabe für die Zukunft wird sein, die Nutzung und Bereitstellung solcher Informationen und Tools entlang der Lieferkette zu verbessern.

Neben kompromittierten Bibliotheken können jedoch auch Container-Images zu Sicherheitslücken werden. Denn auch hier ist es eher üblich, statt von Grund auf ein eigenes Image zu generieren, ein Passendes zu suchen, auf dem der Hersteller aufbaut. Und wie bei Bibliotheken gilt auch hier: Ein kompromittiertes Original-Image reicht aus, alle darauf Basierenden zu infizieren. Die Verwendung von Container-Images hat dabei noch einen weiteren schwerwiegenden Nachteil: Zwar werden ähnlich wie bei Bibliotheken die Abhängigkeiten über Namen und Versionsbezeichner spezifiziert, doch enthalten Definitionen für Container-Images standardmäßig keine „Lock“-Dateien, wie sie bei Paketmanagern üblich sind. Diese Dateien sorgen für reproduzierbare Builds und enthalten die exakte Version inklusive Hash. Das bedeutet, dass eine identische Build-Anweisung für Container-Images (Dockerfile) zu unterschiedlichen Zeitpunkten unterschiedliche Images erzeugen kann. Natürlich ist es möglich, diese Lockfiles „nachzurüsten“ – standardmäßig dazu gezwungen, wird aber niemand. Die gute Nachricht ist: auch Container-Images und Build-Instruktionen sind letztlich Artefakte, aus denen SBOM-Tools Abhängigkeiten und Versionen extrahieren. Diese können dann mit entsprechenden Tools auf Schwachstellen überprüft und zentral verwaltet werden.

Während Bibliotheken und Container-Images von Softwareentwicklern sehr bewusst eingesetzt werden, erweisen sich Firmwares als wesentlich undurchsichtiger. Es gibt eine Vielzahl von Spielarten, die von kompletten (embedded) Linux-Systemen wie buildroot/busybox oder Yocto über proprietäre Betriebssysteme bis hin zu Firmware in binärer Form reichen. Letztere wird zum Beispiel in Form von Treibern für Gerätefunktionen wie WiFi, Bluetooth oder GPS bereitgestellt und ist oft für deren Nutzung unerlässlich. Systeme wie buildroot oder Yocto, die Embedded Linux verwenden, können oft einfach in SBOM-Prozesse integriert werden, da sie die notwendigen Informationen während des Buildprozesses zur Verfügung stellen. Schwieriger wird es bei anderen Betriebssystemen oder Low-Level-Firmware in Treibern. Diese sind oft in einem proprietären Format gespeichert, verschlüsselt, statisch verlinkt oder eine Kombination dieser Eigenschaften. Dadurch ist es oft nicht möglich, SBOM-Daten zu extrahieren.

Udo Schneider, Trend Micro

„Cyberresilienz für Softwarelieferketten ist ein Thema, das alle Beteiligten angeht. Nicht nur aus sicherheitstechnischer Sicht, sondern auch weil aktuelle und zukünftige Vorschriften und Gesetze dies schlichtweg erfordern.“

Udo Schneider, Trend Micro

Ein oftmals vernachlässigter Aspekt der Supply Chain ist nicht zuletzt die Entwicklungsumgebung selbst. Damit ist nicht nur der gewählte Editor oder die IDE (Integrated Development Environment) gemeint, sondern alle Werkzeuge und Abhängigkeiten, die im Entwicklungsprozess verwendet werden – von Editoren/IDEs über Codegeneratoren bis hin zum eigentlichen System, auf dem die Entwicklung stattfindet. Häufig wird die Ansicht vertreten, dass die Softwarelieferkette erst mit dem eigenen Quellcode in schriftlicher Form im Versionsverwaltungssystem beginnt. Das bedeutet, dass lediglich aus dem Sourcecode oder den Build-Artefakten/Release-Daten SBOMs erzeugt werden. Diese Sichtweise ist jedoch in vielen Fällen unzureichend, da häufig auch nicht-textuelle Daten berücksichtigt werden müssen, die für den Build benötigt werden oder im finalen Release enthalten sind. Eine mögliche Lösung besteht darin, auch das Entwicklungssystem umfassend und deterministisch inklusive von Abhängigkeiten und Versionen zu beschreiben und zu betreiben (zum Beispiel in einem Container). Auf diese Weise kann ein neuer Entwickler das Respository auschecken und schnell produktiv werden, ohne erst mit viel Trial-and-Error die genaue Kombination von Compiler und Libraries für die Kompilation herausfinden zu müssen.

Auch KI ist ein Einfallstor

Das Thema künstliche Intelligenz lässt sich heutzutage kaum ausklammern. Auch die Software Supply Chain wird durch das Aufkommen der Technologie weiter verkompliziert. So laden die KI-Runtimes beispielsweise ihre Modelle in der Regel auf verschiedenen Backends (für verschiedene CPU-, GPU- oder NPU-Modelle) dynamisch nach. Das bedeutet, dass die Basis-Runtime sich mit SBOMs zwar gut dokumentieren lässt, bei den nachgeladenen Modulen fällt das aber wesentlich schwerer. Zudem werden für das Training eines Large Language Models (LLM) enorme Mengen an CPU/GPU-Ressourcen benötigt, die in den meisten Fällen nur sinnvoll in der Cloud gemietet werden können. Die gesamte Trainingsumgebung – einschließlich der Softwarestände von Betriebssystem, Bibliotheken und Treibern – wird dadurch zu einem Teil der Softwarelieferkette, die geschützt und für eine Risikobewertung dokumentiert werden muss.

Eine weitere offensichtliche Problematik stellt die Qualität und das Format der KI-Daten dar. Wenn das Unternehmen selbst nicht über die erforderlichen Daten verfügt, muss es beispielsweise auf Daten aus anderen Quellen zurückgreifen. Die Gefahr, dass diese externen Quellen kompromittiert sein könnten, ist dabei immer gegeben. Häufig werden zudem Formate verwendet, die sich von den Trainingsframeworks direkt und ohne Parsing verarbeiten lassen. Dies bedeutet beispielsweise bei der Verwendung von Python-basierten Frameworks, dass die Daten im sogenannten „Pickle“-Format gespeichert werden. Mit Pickle können Daten und Objekte in Python serialisiert und deserialisiert werden. Dazu gehört auch die Serialisierung von Closures oder Lambda-Ausdrücken, die beim Einlesen der Daten ausgeführt werden. Dies lässt sich durch potenzielle Angreifer ausnutzen, um beliebigen Code zu injizieren.

Alle diese Komponenten – von Bibliotheken über Container-Images und IDEs bis hin zu KI-Modellen – müssen letztlich als angreifbare Teile der Softwarelieferkette betrachtet werden. Das bedeutet die Verpflichtung, diese zu dokumentieren und laufend zu bewerten. Nur so können die Hersteller den gesetzlichen Rahmenwerken wie NIS2, DORA oder CRA entsprechen.

Fazit: Cyberresilienz fußt auf umfassender Dokumentation und Bewertung

Cyberresilienz für Softwarelieferketten ist ein Thema, das alle Beteiligten angeht. Nicht nur aus sicherheitstechnischer Sicht, sondern auch weil aktuelle und zukünftige Vorschriften und Gesetze dies schlichtweg erfordern.

Für die Hersteller ist es geboten, die Risiken entlang der Softwarelieferkette laufend und umfassend zu dokumentieren und zu bewerten. Dazu gehört auch die Einholung von Sicherheitsinformationen aus der Lieferkette.

Grundsätzlich ist es ratsam, diese Informationen automatisiert zu erfassen und bereitzustellen, um den regulatorischen und gesetzlichen Verpflichtungen als Hersteller nachzukommen. Zu diesem Zweck gibt es mittlerweile ausgereifte Lösungen am Markt. Die Fähigkeit zu einer schnellen und weitestgehend automatisierten Risikobewertung wird dabei in Zukunft einen erheblichen Wettbewerbsvorteil darstellen.

Die Autoren sind für den Inhalt und die Richtigkeit ihrer Beiträge selbst verantwortlich. Die dargelegten Meinungen geben die Ansichten der Autoren wieder.

Erfahren Sie mehr über IT-Sicherheits-Management