Sicherheitsverschuldung, oder wenn Bugs böse werden
Von Zeit zu Zeit wird die IT-Welt von einer wieder aufkeimenden Besorgnis erfasst - manchmal ist es ein flüchtiger Trend, manchmal ein bedeutendes Problem. In letzter Zeit macht der Begriff "Sicherheitsverschuldung" auf allen IT-Nachrichtenplattformen die Runde. In diesem Artikel sollen das Wesen der Sicherheitsschuld und ihre Auswirkungen erläutert werden.
Von der technischen Schuld zur Sicherheitsschuld
Das Konzept der "technischen Verschuldung" ist vielen bekannt; es bezieht sich auf die Herausforderungen, die entstehen, wenn Projekte über ein überschaubares Maß hinauswachsen. Diese "Größe" kann in Codezeilen, Modulen, Funktionen oder anderen Metriken gemessen werden und spiegelt die Fähigkeit eines Teams wider, gleichzeitig neue Funktionen hinzuzufügen und bestehenden Code zu pflegen.
So ist es beispielsweise um Größenordnungen schwieriger, einer ausgereiften Anwendung neue Funktionen hinzuzufügen als einer Anwendung, die erst am Anfang der Entwicklung steht. Es gibt weniger bewegliche Teile und weniger Wechselwirkungen zwischen den verschiedenen Teilen des Codes, so dass das Hinzufügen neuer Funktionen weniger wahrscheinlich zu einem Bruch der bestehenden Funktionen führt. Wenn sich die Anwendung weiterentwickelt, kann jede Änderung zu einer unerwarteten Interaktion an einer anderen Stelle des Codes führen. In der Sprache der Entwickler heißt das einfach "Sie haben einen Fehler hinzugefügt". Angesichts begrenzter Zeit und Ressourcen müssen die Entwickler neue Entwicklungen mit Fehlerbehebungen jonglieren, was den Gesamtfortschritt verlangsamt. Dieser Wartungsrückstand stellt eine "technische Schuld" dar.
Einige - wenn nicht alle - dieser Fehler können, wenn sie lange genug im Code verbleiben, können sich zu Sicherheitsproblemen entwickeln. Zum Beispiel kann eine überlaufende oder unterlaufende Variable irgendwo einfach bedeuten, dass ein Bericht einen schlechten Wert erhält, oder, wenn jemand einen Weg findet, dies auszulösen, kann dies zu einer Beschädigung des Speichers in nicht damit verbundenen Teilen der Anwendung führen. Dies ist die "Sicherheitsschuld", d. h. die Sicherheitslücken, die sich im Code befinden, manchmal monatelang oder sogar jahrelang, bis jemand dazu kommt, sie zu beheben. Bleiben diese Schwachstellen unbeachtet, können sie ausgenutzt werden, bevor sie behoben sind.
Warum also feiert sie ein Comeback?
Der Hauptgrund dafür ist die Komplexität. Die Codebasis wird immer größer. Es werden immer neue Funktionen zur Software hinzugefügt, nie umgekehrt. Das heißt, es wird mehr Code hinzugefügt, nicht entfernt. Unser menschliches Gehirn hat Schwierigkeiten, die Feinheiten unserer digitalen Kreationen vollständig zu erfassen.
Nehmen wir die Codebasis des Linux-Kernels, die von 2,4 Millionen Codezeilen im Jahr 2001 auf über 20 Millionen im Jahr 2015 anwuchs. Niemand, und schon gar nicht ein Team, ist in der Lage, alle Aspekte angemessen zu erfassen. Jedes Mal, wenn jemand eine neue Codezeile hinzufügt, kann diese gut funktionieren oder an anderer Stelle eine Kernschmelze auslösen. Wenn man eine Münze wirft, hat man die gleichen Chancen.
Dies gilt nicht nur für den Kernel oder für Projekte dieser Größenordnung oder sogar für Open-Source-Projekte überhaupt. Diese Komplexitätszunahme findet auch bei proprietärer Software mit geschlossenem Quellcode statt, wir haben nur keine Metriken für die Codegröße, die das belegen könnten. Zum Vergleich: Windows 95 wurde auf 13 Disketten mit 1,68 MB ausgeliefert (kein Tippfehler, diese Disketten Diese Disketten verwendeten ein anderes Spurlayout, um mehr Daten unterzubringen, und dienten gleichzeitig als Kopierschutzmechanismus). Windows 11 wird als ca. 5 GB große Iso-Datei ausgeliefert.
Ja, die Codebasis wurde erweitert.
Es liegt auch nicht daran, dass die Entwickler plötzlich schlechter geworden sind. Der typische Entwickler ist vielleicht in der Lage, ein paar Dutzend Codezeilen aus dem Gedächtnis genau zu verstehen. Ein guter Entwickler kann das Doppelte oder Dreifache davon verstehen (ich bleibe absichtlich vage, da dies schwer zu beurteilen ist). Für alle ist das Betrachten von Code, den sie ein paar Tage oder Wochen nicht gesehen haben wie das erstmalige Lesen einer Fremdspracheund der Kontextwechsel braucht Zeit.
Es ist nicht mehr selbstverständlich, ganze Projekte zu verstehen. Die Tatsache, dass wir Fehler programmieren, ist eine deutliche Erinnerung an diese Tatsache.
Ist das alles?
Das Problem wird durch die "versteckte Komplexität" verschärft, die mit jeder hinzugefügten Bibliothek oder Drittanbieterkomponente entsteht. In einem kürzlich veröffentlichten Bericht wurde hervorgehoben, dass ein durchschnittliches Java-Projekt etwa 150 Abhängigkeitenaufweist, ein deutlicher Anstieg gegenüber dem Vorjahr. Diese Komplexität vergrößert die ohnehin schon schwierige Aufgabe, den Code von Drittanbietern zu verwalten.
Umgang mit Sicherheitsschulden
All dieser Code enthält von Natur aus Fehler, von denen viele unmittelbar Sicherheitsprobleme darstellen. Die korrekte und rechtzeitige Behandlung dieser Fehler ist schwierig. Wie schwierig, hängt von mehreren Faktoren ab:
- Wie schnell sie entdeckt werdenwas wiederum von den Tests abhängt, die in der Entwicklungs- und Build-Pipeline durchgeführt werden: Wenn Ihre Sicherheitsprüfungen am Ende eines langen Merge-Fensters mit mehreren Entwicklern stattfinden, die über einen längeren Zeitraum Code übertragen, ist der Aufwand des ursprünglichen Entwicklers für die Behebung des Problems viel höher, da er sich nicht mehr daran erinnern kann, warum etwas so implementiert wurde, wie es war.
- Wie umfassend Ihre Tests sind: Testen Sie nur auf bestimmte Probleme? Vielleicht sucht die statische Analyse nur nach bestimmten Mustern, wie falsch typisierte Variablen, Pufferüberläufe oder die Verwendung von NULL. Etwas anderes kann unbemerkt bleiben, bis es in freier Wildbahn gefunden wird.
- Die Gesamtzahl der festgestellten Probleme: Wenn Sie einen großen Rückstand an Sicherheitsproblemen haben, haben Sie dann die Ressourcen - Zeit, Know-how, Arbeitskräfte -, um sie alle zu beheben? Setzen Sie Prioritäten? Was ist, wenn an anderer Stelle etwas passiert, das ein Problem mit niedriger Priorität plötzlich wichtiger werden lässt? Ist Ihr System flexibel genug, um darauf zu reagieren?
Es gibt viele Aspekte der Sicherheitsschuld, und dieser Artikel befasst sich nur mit einigen Kernfragen. Sein Ziel war es, auf das Problem aufmerksam zu machen, dass technische Schulden zu Sicherheitsschulden werden, wenn die Komplexität so groß wird, dass ein Entwickler oder ein Team nicht mehr in der Lage ist, sie ordnungsgemäß zu verwalten.
Es gibt einige Taktiken, um das Problem anzugehen: bessere Sicherheitstests, frühere Sicherheitstests, Sicherheitstests vor der Übergabe des Codes (im Gegensatz zu einer Überprüfung erst nach der Übergabe), Peer Review, Auslagerung der Prüfung von Drittanbieter-Bibliotheken an eine dritte Parteioder sogar die Einstellung von mehr Entwicklern, wenn die Codebasis wächst. Alleine wird keiner dieser Vorschläge das Problem vollständig lösen, aber zusammengenommen könnten sie die Komplexität noch eine Weile in Schach halten und die Auswirkungen abmildern.
Hinweis: Wenn Sie mehr über das Problem erfahren möchten, finden Sie im Podcast "Enterprise Linux Security" eine Folge 84 zu diesem Thema. Sie finden sie auf allen Podcast-Plattformen oder auf YouTube mit einer Live-Aufnahme.


