Software besteht heute zu einem sehr großen Teil aus fremdem Code, etwa aus Bibliotheken und Frameworks. Das ermöglicht es uns, effizient Softwarelösungen zu entwickeln, da nicht jeder das Rad neu erfinden muss. Aber es führt auch dazu, dass man sich die Probleme und insbesondere die potenziellen Sicherheitslücken des fremden Codes in Haus holt.

Und was noch hinzukommt: Bibliotheken und Frameworks, die bisher keine bekannten Sicherheitslücken (CVEs) aufweisen, können dies aber schon morgen oder übermorgen tun! Soll heißen: Software, die heute als sicher gilt, ist es morgen vielleicht schon nicht mehr!

In unserer DevOps-Zelle im PPI.X-Team haben wir uns mit diesem Problem beschäftigt und eine effiziente Lösung gefunden, bei der niemand mehr den Task „Prüfe tausende fremde Softwarekomponenten auf Sicherheitslücken in allen Produkten“ auf seiner täglichen To-do-Liste haben muss.

Diese Lösung wollen wir im Folgenden vorstellen.

Wie decken wir Sicherheitslücken (CVEs) toolgestützt auf?

Sicherheitslücken von Fremdsoftware werden in öffentlichen Datenbanken dokumentiert, wie beispielsweise in der CVE-Liste der National Vulnerability Database (NVD): https://cve.mitre.org/. Natürlich ist es nicht sinnvoll, diese Datenbanken per Hand zu durchsuchen – dafür gibt es diverse kommerzielle, aber auch freie Tools auf dem Markt.

Besonders spannend fanden wir die Software Dependency-Track. Sie ist Open Source, bestens dokumentiert und ließ sich sehr einfach in unsere Welt integrieren.

Wie funktioniert Dependency-Track?

Damit Dependency-Track die Prüfungen für eine Software durchführen kann, muss man eine standardisierte, maschinenlesbare Liste der verwendeten Bibliotheken (Dependencies) übergeben – die sogenannten „Software Bill of Materials“ (SBOM). Diese Liste kann sehr einfach ohne manuelle Mühen erstellt werden. Dafür gibt es Programme, wie etwa cdxgen (https://github.com/AppThreat/cdxgen), die SBOM für mehrere Programmiersprachen und Build-Systeme generieren können.

Diese SBOM werden nun eingelesen und die Versionen mit den in Dependency-Track eingebundenen Datenbanken auf Schwachstellen abgeglichen. So sind beispielsweise die obengenannte NVD-CVE-Datenbank oder die Datenbank NPM Security Advisory dort von Anfang an zusammen mit einigen weiteren eingebunden.

Bei Treffern werden die Details zu der jeweiligen Sicherheitslücke in einer übersichtlichen Oberfläche dargestellt. Dort finden sich Informationen wie Bewertung und/oder Kurzbeschreibung der CVE – je nach Qualität der Datenquelle. Optional kann auch geprüft werden, ob es neuere Versionen der Dependency gibt, die einen Fix der Sicherheitslücke beinhalten.

Wie integriere ich die Sicherheitsprüfungen effizient in den agilen Software-Entwicklungsprozess?

Auch wenn uns das Tool viel abnimmt, bleibt eine große Hürde bestehen: nämlich, sich aktiv mit dem Thema auseinanderzusetzen und regelmäßig Dependency-Track aufzurufen. Und wenn wir ehrlich zu uns sind, machen diese regelmäßigen manuellen Tasks nicht besonders viel Spaß.

Daher haben wir entscheiden, die Prüfung in unseren agilen Software-Entwicklungsprozess zu verdrahten. Dafür haben wir in den CI-Pipelines unserer Projekte einen Job angelegt, der automatisiert bei Dependency-Track die bekannten CVEs des entsprechenden Projekts prüft. Gibt es dort Befunde, wird ein Ticket erstellt – dies tut unser lieber Kollege „Dependencybot“, der sich dafür auch am Wochenende und in der Nacht nicht zu schade ist 😉.


Abbildung 1: Ein GitLab-Ticket (Issue), das Sicherheitslücken der beobachteten Software auflistet.

Die Befunde sind sauber dargestellt, gut beschrieben und nach Schweregrad vorbewertet. Die abschließende Bewertung findet durch die Entwickler statt, die sich aber in den allermeisten Fällen an die Ergebnisse von Dependencybot halten – es ist ja in der Regel auch einfacher, ein Paket zu aktualisieren, als zu begründen, warum man mit der Sicherheitslücke trotzdem gut leben kann.

Die Logik, mit der Dependencybot die Tickets pflegt, schützt uns vor Spam und unnötiger Arbeit:

  1. Dependecybot aktualisiert seine Tickets. Kommt eine neue Sicherheitslücke hinzu oder wird eine geschlossen, erzeugt er kein neues Ticket, sondern fügt in der Tabelle eine Zeile hinzu beziehungsweise entfernt eine.
  2. Sind alle Befunde abgearbeitet, werden diese Tickets ebenfalls geschlossen. So vermeiden wir Ticketleichen, bei denen sich jeder fragt „Haben wir das schon gefixt?“.

Wie oft muss ich meine Software prüfen?

Bei aktiven Projekten, in denen die Entwicklung voranschreitet, stellt sich diese Frage nicht wirklich, da die Prüfung bei jedem Code-Update automatisch getriggert wird.

Was aber, wenn die Software sich im Wartungsmodus befindet und aktuell nicht aktiv weiterentwickelt wird? Hierfür haben wir eine Scheduled Pipeline gebaut, die auch ohne Event (Code-Update) in regelmäßigen Abständen losläuft und das Projekt qualitätssichert. In der Wahl der Frequenz ist man natürlich frei – wir haben uns für einen Wochenrhythmus entschieden. So werden wir nicht zu oft alarmiert, haben aber spätestens nach einer Woche im Blick, wie es um die CVEs steht, und entscheiden dann, wie dringend wir darauf reagieren müssen.

Unsere Erfahrung und Fazit
Wir sind aktuell sehr glücklich mit unserer Lösung, denn wir bekommen zeitnah mit, ob unsere Software bekannte Sicherheitslücken aufweist, und können reagieren. Und das funktioniert, ohne dass jemand die Last der nervigen Aufgabe trägt und manuell regelmäßig alles nach Sicherheitslücken absucht.

Zusätzlich bietet Dependency-Track noch weitere interessante Funktionalitäten, die wir in unseren Entwicklungsprozess einbauen wollen – beispielsweise die Prüfung der Lizenzen von Bibliotheken. Dies ist eine derzeit noch manuelle Tätigkeit, die hoffentlich ebenfalls bald wegfällt. Dazu dann mehr in einem später folgenden Blogartikel.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Verwandte Artikel