KI versteht Hand-Skizzen
Screenshot mit eingezeichneten Pfeilen und Kreisen in den Coding-Agenten kopieren: So gelingen kleine Layout-Änderungen ohne lange Beschreibung.
WeiterlesenFachartikel
Welche Bibliotheken stecken eigentlich in meinem Projekt, und in welcher Version? Bei allem, was über Composer, npm oder NuGet kommt, ist das schnell beantwortet. Die Lockfiles wissen Bescheid. Bei älteren Projekten ist das aber nur ein Teil der Wahrheit.
Um genau diese Lücke geht es hier: was eine SBOM ist, warum sie mit dem Cyber Resilience Act an Bedeutung gewinnt und wie das gfd-sbom-kit auch reinkopierte Bibliotheken findet und auf bekannte Sicherheitslücken prüft.
In fast jedem Projekt, das ein paar Jahre alt ist, liegen Dateien, die kein Paketmanager kennt: eine minifizierte JavaScript-Bibliothek im Assets-Ordner, eine PHP-Klasse für den Mailversand, die irgendwann per Hand ins Projekt kopiert wurde, eine DLL, die einfach mit eingecheckt ist.
Für die meisten Scanner sind diese Dateien unsichtbar. Klassische Dependency-Checks lesen Manifest- und Lockfiles aus, und was dort nicht steht, wird nicht geprüft. Wird in so einer Komponente eine CVE veröffentlicht, merkt das niemand. Die verwundbare Version läuft einfach weiter.
Eine SBOM, also eine Software Bill of Materials, ist eine Stückliste der Software. Sie enthält alle Komponenten mit Name, Version und Fundort im Projekt. Dafür gibt es etablierte Standardformate, sodass andere Tools die Liste weiterverarbeiten können.
Mit dem Cyber Resilience Act wird das Thema in der EU auch regulatorisch wichtiger. Wer Software ausliefert, muss zunehmend nachweisen können, was darin steckt und wie er mit Schwachstellen umgeht.
Für meine Projekte habe ich mir dafür ein eigenes Werkzeug gebaut, das gfd-sbom-kit. GFD steht dabei für Goldfadendesign. Ziel war, auch die Komponenten zu erfassen, die an den Paketmanagern vorbei ins Projekt gekommen sind.
Für die Erkennung nutzt das Kit vier Quellen und führt die Ergebnisse am Ende zu einer Liste zusammen, doppelte Treffer werden entfernt. Syft wertet die Manifest- und Lockfiles aus, auch in kopierten Unterordnern. Retire.js erkennt JavaScript-Dateien ohne Paketdatei direkt am Inhalt. Eine eigene Heuristik schaut zusätzlich in die Dateien hinein: Viele Bibliotheken bringen eine README-Datei mit, oder im Quellcode steht oben ein Kommentar mit Komponentenname, GitHub-Repository und Version. Auch diese Angaben werden für die Erkennung herangezogen. Was keine dieser Quellen findet, kann ich in einer manuellen Liste nachtragen.
Die Erkennung habe ich mir dabei nicht komplett selbst ausgedacht. Es gibt Datenbanken und Tools, in denen Bibliotheken mit Versionen, Beschreibungen und teilweise sogar mit Hashes einzelner Dateien hinterlegt sind. Diese Datenbanken sind recht ausführlich. Dadurch lässt sich auch eine einzelne, umbenannte oder minifizierte Datei einer konkreten Bibliothek und Version zuordnen.
Die gefundenen Komponenten werden anschließend mit öffentlichen Schwachstellen-Datenbanken abgeglichen. Die wichtigste Quelle ist OSV.dev von Google. Die Datenbank bündelt unter anderem die GitHub Security Advisories und Meldungen für Packagist, npm und NuGet und liefert auch, ab welcher Version eine Lücke behoben ist. Für Komponenten ohne Paketmanager, etwa PHP selbst, MySQL oder Apache, fragt das Kit zusätzlich die National Vulnerability Database (NVD) der USA über die CPE-Kennung ab. Für JavaScript-Dateien kommen die Befunde aus der Retire.js-Datenbank.
Die Ergebnisse landen zusammen in einer SBOM im offenen CycloneDX-Format. Übertragen werden dabei nur Paketnamen und Versionen, kein Quellcode. Datenbanken, die sich herunterladen lassen, werden lokal zwischengespeichert, damit nicht bei jedem Lauf alles neu geladen werden muss. Aktualisiert wird der Cache einmal täglich. Eine eigene Serverinfrastruktur wie Dependency-Track brauche ich dafür nicht.
Das Kit ist bewusst in Python umgesetzt. In meinen Projekten treffen PHP, .NET und JavaScript aufeinander, und die Entwickler arbeiten nicht alle auf demselben System. Python läuft unter Windows, macOS und Linux gleich. Als Voraussetzung braucht es nur Python und Node.js.
Bei jedem Lauf prüft das Kit, ob es neuere Versionen der eingesetzten Tools gibt, und aktualisiert sie. Das Kit selbst aktualisiert sich dagegen nicht. Neue Versionen kopiere ich bewusst von Hand ins Projekt.
Das Kit ist nicht an ein einzelnes Projekt gebunden. Es liegt in einem eigenen Git-Repository und wird in das jeweilige Projekt kopiert. Über eine kleine Konfiguration lege ich fest, wo die SBOM-Dokumentation und die Ergebnisdateien landen: zum Beispiel direkt im Projekt und mit eingecheckt oder außerhalb, wenn ich sie im Repository nicht haben will.
Am Ende steht eine kurze Zusammenfassung mit einer Ampel. Grün heißt, es gibt keine bekannten Schwachstellen. Gelb heißt, es gibt nur Befunde mit mittlerem oder niedrigem Schweregrad. Rot heißt, es gibt kritische oder hohe Befunde.
Bei jedem Befund sehe ich direkt, in welcher Datei die Komponente liegt und ab welcher Version die Lücke geschlossen ist. Die SBOM selbst wird bei jedem Lauf neu erzeugt und muss nicht per Hand gepflegt werden. Dabei entstehen zwei Dateien: eine Markdown-Datei als Dokumentation für Menschen und eine maschinenlesbare Datei, die andere Tools weiterverarbeiten können.
Die Ergebnisse eignen sich auch gut für einen Coding-Agenten wie Claude Code. Ich gebe ihm die Liste und sage ihm, er soll die betroffenen Komponenten aktualisieren. Er kann direkt im Projekt nachsehen, was sich geändert hat. Ich kann ihn auch Bibliotheken verschieben lassen, zum Beispiel wenn eine Bibliothek doppelt im Projekt liegt. Mit den Daten, die das Kit erzeugt, kann er dabei sehr gut arbeiten.
Wichtig ist mir dabei: Die Komponenten im Projekt werden auf keinen Fall automatisch aktualisiert. Weder das Kit noch der Agent entscheiden das selbst. Der Anstoß dazu muss immer bewusst von mir kommen.
Das Testen liegt danach natürlich wieder bei mir. Je nachdem, was und wie viel geändert wurde, kann das ziemlich umfangreich werden, vor allem bei größeren Versionssprüngen und erst recht, wenn Breaking Changes dabei sind.
Im Moment starte ich den Check noch selbst. Als Nächstes soll er fest in den Deployment-Prozess: Steht die Ampel auf Rot, wird die Veröffentlichung gestoppt. Außerdem soll der Check wöchentlich im Hintergrund laufen, zum Beispiel über n8n. Neue CVEs werden ständig veröffentlicht, auch für Code, an dem sich seit Monaten nichts geändert hat.
Ein Dependency-Check, der nur Lockfiles liest, prüft nur das, was ohnehin schon sauber verwaltet wird. Die eigentlichen Altlasten liegen oft daneben. Gerade bei gewachsenen Projekten lohnt es sich, das ganze Projekt anzuschauen und nicht nur die Paketdateien.
Wie gehst du damit um? Prüfst du nur deine Paketmanager, oder hast du auch die reinkopierten Bibliotheken im Blick?
Das könnte dich auch interessieren
Screenshot mit eingezeichneten Pfeilen und Kreisen in den Coding-Agenten kopieren: So gelingen kleine Layout-Änderungen ohne lange Beschreibung.
WeiterlesenUmstieg von Windows 10 mit MAMP auf Ubuntu mit Docker und DDEV: pro Projekt eine eigene Umgebung mit passender PHP-Version, Datenbank und Webserver.
WeiterlesenErfahrungen mit Claude Code: parallele Agenten, Review, Projektregeln, Randfälle und Spezifikation vorab. Die Arbeit verschiebt sich vom Schreiben zum Steuern.
Weiterlesen