Qualität und Sicherheit
Ende 2021 wurde die Schwachstelle Log4Shell in der weit verbreiteten Java-Bibliothek Log4j bekannt. In vielen Firmen begann danach eine tagelange Suche: Steckt die Bibliothek in einem unserer Produkte – und wenn ja, in welcher Version? Wer eine Software-Stückliste hatte, beantwortete die Frage in Minuten. Mit dem Cyber Resilience Act wird diese Stückliste für Hersteller zur Pflicht.
Was in eine SBOM gehört
Der CRA definiert die Software-Stückliste, englisch Software Bill of Materials (SBOM), als formale Aufzeichnung der Einzelheiten und Lieferkettenbeziehungen der Komponenten, die in der Software eines Produkts enthalten sind. Praktisch ist das eine maschinenlesbare Liste aller Bibliotheken, Pakete und Module. Je Komponente gehören mindestens dazu:
- Name und Version,
- Hersteller bzw. Lieferant,
- eine eindeutige Kennung, meist als Package URL, etwa
pkg:nuget/Newtonsoft.Json@13.0.3, - eine Prüfsumme der ausgelieferten Datei,
- die Lizenz,
- die Abhängigkeiten zu anderen Komponenten.
Was nicht hineingehört, sind Schwachstellen. Ob eine Lücke Ihr Produkt tatsächlich betrifft, halten Sie getrennt fest, etwa in einem VEX-Dokument (Vulnerability Exploitability eXchange).
Was der CRA verlangt – und was nicht
Anhang I Teil II Nr. 1 fordert eine SBOM in einem gängigen maschinenlesbaren Format, aus der zumindest die obersten Abhängigkeiten hervorgehen. Sie ist Teil der technischen Dokumentation und geht auf begründetes Verlangen an die Marktüberwachungsbehörde. Veröffentlichen müssen Sie sie nicht. Stellen Sie sie Ihren Kunden zur Verfügung, nennen Sie in den Nutzerinformationen, wo sie zu finden ist. Ein festes Format schreibt die Verordnung bisher nicht vor; die Kommission kann es per Durchführungsrechtsakt festlegen.
Einen guten Maßstab gibt schon heute die Technische Richtlinie TR-03183-2 des BSI. Version 2.1.0 verlangt JSON oder XML im Format CycloneDX ab Version 1.6 oder SPDX ab Version 3.0.1. Je Komponente fordert sie unter anderem Ersteller, Name, Version, Dateiname, Lizenz, Abhängigkeiten und einen SHA-512-Hashwert. Abhängigkeiten werden rekursiv aufgelöst, mindestens bis einschließlich der ersten Komponente außerhalb Ihres Lieferumfangs.
CycloneDX oder SPDX?
| CycloneDX | SPDX | |
|---|---|---|
| Herkunft | OWASP, als ECMA-424 standardisiert | Linux Foundation, Version 2.2.1 als ISO/IEC 5962:2021 |
| Schwerpunkt | Sicherheit und Lieferkette, VEX im selben Format möglich | ursprünglich Lizenzen und Compliance, ab Version 3 auch Sicherheit |
| Aktuelle Version | 1.7 | 3.0.1 |
Beide Formate erfüllen den CRA. Entscheidend ist, was Ihre Werkzeuge und Kunden verarbeiten. Für den Abgleich mit Schwachstellendatenbanken, etwa mit OWASP Dependency-Track, ist CycloneDX verbreitet; Lizenzprüfungen arbeiten traditionell gern mit SPDX. Umwandeln lässt sich zwischen beiden, aber nicht immer verlustfrei.
Die SBOM im Build erzeugen
Von Hand gepflegt, ist eine SBOM mit dem nächsten Paket-Update falsch. Sie gehört in den Build, und zwar für genau die Version, die ausgeliefert wird. Für .NET gibt es das Kommandozeilenwerkzeug CycloneDX, für Python cyclonedx-py, für SPDX zum Beispiel Microsofts sbom-tool:
# .NET: Werkzeug einmalig installieren, dann bei jedem Release-Build
dotnet tool install --global CycloneDX
dotnet-CycloneDX Produkt.sln -o sbom -fn produkt.cdx.json -F Json -t -sn Produkt -sv 2.4.0
# Python: aus der requirements.txt
cyclonedx-py requirements requirements.txt --of JSON -o sbom/werkzeug.cdx.json
-sv setzt die Produktversion, -t lässt Testprojekte weg. Danach prüft ein kleines Skript, ob die Stückliste vollständig ist, und lässt den Build scheitern, wenn Angaben fehlen – zum Beispiel Lizenzen, die das Werkzeug nicht auflösen konnte:
import json
import sys
with open("sbom/produkt.cdx.json", encoding="utf-8") as datei:
komponenten = json.load(datei).get("components", [])
fehler = []
for komponente in komponenten:
name = komponente.get("name", "?")
for feld in ("version", "purl", "licenses", "hashes"):
if not komponente.get(feld):
fehler.append(f"{name}: {feld} fehlt")
print(f"{len(komponenten)} Komponenten geprüft, {len(fehler)} Lücken")
for zeile in fehler:
print(zeile)
sys.exit(1 if fehler else 0) # Lücken lassen den Build scheitern
Was die Werkzeuge nicht finden
Werkzeuge lesen Paketmanager. Was an ihnen vorbei ins Produkt kommt, fehlt: kopierte DLLs, C- und C++-Bibliotheken, zugekaufte Module, Firmware, mitgelieferte Laufzeitumgebungen und alles, was der Installer zusätzlich ablegt. Diese Komponenten erfassen Sie einmal in einer Ergänzungsdatei, die der Build mit der erzeugten SBOM zusammenführt, etwa mit dem Befehl merge der CycloneDX-CLI. Bei CAD-Add-ins gilt umgekehrt: Die AutoCAD- oder Revit-DLLs, gegen die Sie bauen, liefern Sie nicht aus. Sie gehören nicht als Komponente in Ihre SBOM, wohl aber als Voraussetzung in die Dokumentation.
Und dann muss die SBOM auch genutzt werden: Archivieren Sie sie je Release mit der technischen Dokumentation und gleichen Sie sie laufend mit Schwachstellendatenbanken ab – neue Schwachstellen betreffen auch Versionen, die längst beim Kunden laufen.
Hinweis: Dieser Artikel gibt einen technischen Überblick und ist keine Rechtsberatung.
Typische Fehler
- Die SBOM aus dem Quellcode statt aus dem Build erzeugen. Sie beschreibt dann nicht, was tatsächlich ausgeliefert wird.
- Nur die direkten Pakete erfassen. Viele Schwachstellen stecken in transitiven Abhängigkeiten.
- Eine SBOM für alle Versionen. Jede ausgelieferte Version braucht ihre eigene.
- Schwachstellen in die SBOM schreiben statt in ein eigenes VEX-Dokument.
- Kopierte DLLs und C++-Bibliotheken vergessen, weil kein Paketmanager sie kennt.
So helfen wir
- SBOM im Build: Wir richten die Erzeugung für .NET, C++ und Python ein, ergänzen fehlende Komponenten und prüfen die Vollständigkeit – als Teil unserer Leistungen zum Cyber Resilience Act.
- Schwachstellen: Wir bewerten Treffer für Ihr Produkt und beheben sie: Qualitätsprüfung und Code-Review.
- Einstieg: Ein Beratungstag zum Festpreis klärt, wo Ihre Produkte stehen. Oder vereinbaren Sie ein Erstgespräch.
Quellen: Verordnung (EU) 2024/2847, Art. 3 Nr. 39, Art. 13 Abs. 24, Anhang I Teil II Nr. 1, Anhang II Nr. 9, Anhang VII sowie Erwägungsgrund 77, EUR-Lex; BSI TR-03183-2, Version 2.1.0; CycloneDX; SPDX. Stand: Oktober 2026.
