Der Patch-Rucksack

Warum „kritisch zuerst“ das Wartungsfenster verschwendet und wie man es besser füllen kann.

Du kannst nicht alles patchen. Niemals!

Das ist keine Nachlässigkeit, sondern die Normalität jeder realen IT-Landschaft. Es gibt immer mehr offene Schwachstellen als es Hände gibt, die sie schließen könnten, und immer mehr Patches als Minuten im nächsten Wartungsfenster vorhanden sind. Die Frage ist deshalb nie, ob man priorisiert, sondern die Frage ist, wie man priorisiert. Die verbreitetste Methode dabei ist nachweislich eine der schlechtesten.

Die Standardantwort und ihr blinder Fleck

Wie priorisieren die meisten Organisationen? Nun: Nach Schweregrad. Die kritischen Schwachstellen kommen zuerst, dann die hohen, dann die mittleren, bis das Wartungsfenster voll ist. Das klingt sehr vernünftig, es klingt sogar sehr verantwortungsvoll: Man kümmert sich immer zuerst um das Schlimmste.

Der blinde Fleck steckt im Wort „zuerst“. Denn diese Reihenfolge betrachtet jeden Patch für sich alleine – seine Schwere – dabei ignoriert man aber etwas sehr Entscheidendes: Patches konkurrieren um dieselbe knappe Ressource. Nämlich um die Zeit im vorhandenen Wartungsfenster, um das Personal und um die Testkapazitäten. Sobald aber Dinge um eine begrenzte Ressource konkurrieren, ist die Reihenfolge, die sich nur nach einem einzigen Kriterium bestimmt, fast immer die falsche Antwort. Das ist keine Meinung aus dem Luftleeren Raum, das ist ein Ergebnis und man kann es vorrechnen.

Ein Beispiel, das man nachrechnen kann

Nehmen wir ein Wartungsfenster von 15 Personenstunden und fünf Patch-Kandidaten. Jeder Patch hat seinen speziellen Aufwand (wie viele Stunden er kostet) und einen Nutzen (wie viel Risikopunkte er abbauen kann — dazu gleich mehr). Die Zahlen sind illustrativ, aber die Struktur ist echt:

Patch A: Eine kritische Remote-Code-Execution-Lücke. Aufwand: 14 Stunden (aufwändig, weil mehrere Systeme betroffen sind und ausgiebig getestet werden muss). Risikoabbau: 100 Punkte.

Patch B und C: Je eine hoch eingestufte Lücke, Privilege-Escalation und SQL-Injection. Aufwand je 5 Stunden. Risikoabbau 55 beziehungsweise 50 Punkte.

Patch E: Eine mittlere Lücke, 3 Stunden, Risikoabbau 30. 

Und Patch F: Eine niedrige, 2 Stunden, Risikoabbau 14.

Jetzt vergleichen wir zwei potentielle Strategien im selben 15-Stunden-Fenster.

„Kritisch zuerst“ greift zu Patch A. Der kostet 14 der 15 Stunden. Danach ist eine Stunde übrig. Zu wenig für etwas anderes. Ergebnis: ein Risikoabbau von 100, und das Fenster ist voll verbraucht.

Die optimale Wahl lässt den teuren Kritischen bewusst liegen und behebt stattdessen B, C, E und F. Das sind zusammen 5 + 5 + 3 + 2 = 15 Stunden und das Fenster ist exakt gefüllt. Der Risikoabbau: 55 + 50 + 30 + 14 = 149.

Gleiches Fenster. Gleicher Aufwand. Aber 49 Prozent mehr abgebautes Risiko.  Alleine durch eine andere Auswahl. „Kritisch zuerst“ hat fast die Hälfte des möglichen Nutzens liegen lassen.

Warum das passiert?

Der Grund ist der eine teure Patch. Patch A ist für sich genommen der wertvollste, denn sein Risikoabbau von 100 ist höher als der jedes Einzelnen der anderen. Aber er ist auch der gefräßigste: Er belegt fast das gesamte Fenster und verdrängt damit vier andere Patches, die zusammen mehr abzubauen in der Lage sind, als er allein es kann.

Das ist die Falle der Priorisierung nach einem einzigen Kriterium. Schwere allein sagt dir, wie viel ein einzelner Patch wert ist aber er sagt nichts dazu aus, wie teuer er dich in Bezug auf alles andere zu stehen kommt. Ein Patch mit hohem Wert und hohem Aufwand kann eine schlechtere Investition sein als drei Patches mit mittlerem Wert und geringem Aufwand. Man erkennt das nur, wenn man Aufwand und Nutzen gemeinsam betrachtet und die Auswahl als Ganzes trifft und nicht nach Patch für Patch.

Das ist ein bekanntes Problem: das Rucksack-Problem

Was wir hier lösen, hat einen Namen und eine über hundertjährige Geschichte in der Mathematik: das Rucksackproblem.

Die Metapher ist wörtlich zu nehmen. Stell dir einen Rucksack mit begrenztem Fassungsvermögen vor und eine Menge von Gegenständen. Jeder Gegenstand hat ein Gewicht und einen bestimmten Wert. Welche Teilmenge packst du ein, um den Gesamtwert des Rucksacks zu maximieren, ohne das du den Rucksack sprengst? Das übersetzt in unsere Welt: Der Rucksack ist das Wartungsfenster, das Fassungsvermögen ist das Zeitbudget, die Gegenstände sind die Patches, ihr Gewicht ist der Aufwand und ihr Wert ist der Risikoabbau. Wir sollen nun den wertvollsten Rucksack packen, der ins Zeit-Fenster passt.

Dass es sich um ein wohldefiniertes, seit Jahrzehnten studiertes Problem handelt, ist eine gute Nachricht: Denn es gibt exakte Verfahren, die die beste Auswahl garantiert finden, und schnelle Näherungsverfahren für sehr große Fälle. Man muss das Rad also nicht neu erfinden. Man muss nur erkennen, dass dieses Problem ein Modell für die Patch-Priorisierung ist. Daher können wir aufhören, es mit einer simplen Sortierung zu versuchen.

Die naheliegende Verbesserung und ihre Grenze

Wer bis hier gefolgt ist, hat vermutlich schon eine bessere Idee als „kritisch zuerst“: Warum nicht nach dem Wert pro Stunde sortieren? Also den Patch zuerst nehmen, der pro investierter Stunde am meisten Risiko abbaut, dann den nächstbesten, und so weiter, bis das Fenster voll ist. Das ist eine deutlich klügere Heuristik und sie hätte in unserem konkreten Beispiel sogar die optimale Lösung gefunden.

Aber: Und das ist eine lehrreiche Feinheit. Diese „Dichte-Heuristik“ ist nicht garantiert optimal. Ein kleines Gegenbeispiel: Drei Patches, ein Budget von 10 Stunden. Patch A kostet 6 Stunden und bringt 60, hat also die beste Dichte, 10 pro Stunde. Patch B und C kosten je 5 Stunden und bringen je 48, Dichte 9,6. Die Dichte-Heuristik greift zuerst zu A und dann bleiben nur 4 Stunden, in die nichts mehr passt. Ergebnis: 60. Die optimale Wahl wäre B und C zusammen gewesen: 10 Stunden exakt, Risikoabbau 96. Die Heuristik verliert ein Drittel.

Das ist kein Argument gegen diese Heuristik. Sie ist schnell und meist gut. Es ist ein Argument dafür, den Unterschied zu erkennen: Eine Faustregel ist eine Faustregel, kein Optimum. Wo es auf jeden Prozentpunkt Risikoabbau ankommt, rechnet man exakt, statt zu raten. Und wo eine schnelle Näherung reicht, nimmt man sie bewusst und im klaren Wissen, dass sie nur eine Näherung ist.

Der ehrliche Kern: woher kommen die Wert-Zahl?

Jetzt zum unbequemsten Teil, den ich nicht überspringen will, weil die gesamte Rechnung an ihm hängt. Der „Risikoabbau“, die Wert-Zahl jedes Patches fällt nicht vom Himmel. Die schönste Optimierung ist wertlos, wenn diese Eingangszahlen falsch sind.

Woher also nimmt man sie? Der erste Reflex ist, den CVSS-Score zu verwenden. Also die Schwere aus dem Scanner. Aber wer meine früheren Überlegungen kennt, ahnt schon, dass das leider zu kurz greift. Die Schwere einer Schwachstelle sagt nichts über ihre Reichweite (siehe Blast Radius): Eine mittelschwere Lücke in einer zentralen, viel genutzten Komponente kann ein weit größeres Risiko darstellen als eine kritische in einem isolierten System. Der Wert eines Patches hängt also nicht nur an seiner Schwere, sondern an seiner Position im Abhängigkeitsgraphen.

Und es kommt nun eine zweite Schicht dazu: Der „vermiedene Schaden“ ist auch keine feste Zahl, sondern eine Verteilung. Eine Schwachstelle führt selten zu genau einem einzelnen Schadensbetrag. Sie führt im Allgemeinen zu einem ganzen Spektrum möglicher Verluste, von harmlos bis katastrophal. Wer den Wert eines Patches nun als einzelne Zahl ansetzt, wählt implizit eine Kennzahl dieser Verteilung aus, und, wie ich an anderer Stelle argumentiert habe, ist der Durchschnitt dafür oft die schlechteste Wahl.

Man erkennt: Die Optimierung ist die letzte Stufe einer Kette. Sie setzt voraus, dass man Reichweite und Schadensverteilung schon sauber erarbeitet hat. Ist diese Grundlage gut, dann verwandelt die Optimierung sie in eine belastbare Entscheidung. Ist sie schlecht, optimiert man präzise auf genau die falschen Zahlen. Beides gehört zusammen und keines ersetzt das andere.

Es lohnt sich, diesen Gedanken einen Schritt weiterzuführen, denn er berührt den Kern jeder ernsthaften Risikoarbeit. Ein „Risikoabbau von 100“ ist, streng genommen, eine Kurzschrift für eine ganze Kette von Schätzungen: Wie wahrscheinlich ist die Ausnutzung dieser Lücke? Welche Systeme sind über den Abhängigkeitsgraphen erreichbar? Welche Verluste, als Verteilung, nicht als Punkt, drohen im konkretem Ausnutzungsfall? Und um welchen Betrag senkt der Patch diese erwarteten Verluste? Jede dieser Fragen ist selbst ein kleines Modell mit eigenen Annahmen. Die Wert-Zahlen sind deren Ergebnis.

Das klingt nach viel Anstrengung und Arbeit – ist es auch! Aber die Alternative ist nicht, es sich einfach zu machen. Die Alternative ist, dieselben Fragen unausgesprochen und schlecht zu beantworten. Wer „kritisch zuerst“ sagt, hat all diese Schätzungen ebenfalls getroffen. Allerdings nur implizit für sich allein, indem er sie durch einen einzigen Scanner-Score ersetzt hat. Der Unterschied zwischen guter und schlechter Risikoarbeit ist nicht, ob man schätzt, sondern ob man die Schätzung offenlegt und prüfbar macht. Genau das leistet eine saubere Quantifizierung: Sie macht aus einem Bauchgefühl eine Kette nachvollziehbarer, einzeln bestreitbarer Annahmen. Und erst auf dieser Kette kann eine Optimierung sinnvoll aufsetzen.

Was Praktiker daraus mitnehmen

Die Botschaft ist nicht: „Patcht die Kritischen nicht.“ Manchmal ist der teure kritische Patch genau richtig, nämlich dann, wenn sein Risikoabbau so hoch ist, dass er die verdrängten kleineren tatsächlich aufwiegt. Die Botschaft soll sein: Diese Abwägung ist berechenbar, und das Bauchgefühl trifft sie meistens falsch.

Konkret heißt das dreierlei. 
Erstens: Bewerte Patches nach Aufwand und Nutzen gemeinsam, nie nur nach der Schwere allein. 
Zweitens: Triff die Auswahl als Ganzes. Welche Kombination füllt das Fenster am besten, und nicht Patch für Patch, von oben nach unten. 
Drittens: Investiere die Anstrengung dorthin, wo sie wirklich zählt. In die Werte-Zahlen, also in die Reichweite und deren Schadensverteilungen. Die Optimierung selbst ist der leichteste Teil. Die ehrliche Schätzung ihrer Inputs ist der schwere.

Man muss nichts schon vom ersten Tag an perfekt sein! Schon der Wechsel von „nur nach Schwere sortieren“ hin zu „Aufwand und Nutzen gemeinsam betrachtend“ holt in der Praxis oft den größten Vorsprung heraus. Man braucht keine ausgefeilte Software, um zu erkennen, dass ein 14-Stunden-Patch vier kleinere verdrängt, die zusammen mehr bringen würden. Man braucht nur die Bereitschaft, die Auswahl als Ganzes sehen zu wollen anstatt nur als Rangliste. Der Rest, die exakte Rechnung, die Verfeinerung der Werte-Zahlen, ist dann eine Frage des Reifegrades den man erreichen will und nicht eine für den Einstieg.

Ist das nicht furchtbar aufwändig zu rechnen?

Eine berechtigte Rückfrage: Das Rucksackproblem gilt als „schwer“. Genauer gesagt, es ist NP-schwer. Das bedeutet aber nicht, dass man es in der Praxis gar nicht lösen kann.

„NP-schwer“ ist eine Aussage über das Verhalten im schlimmsten Fall, wenn die Zahlen beliebig groß und ungünstig werden. Für die Größenordnungen, um die es bei Patch-Priorisierung geht, Dutzende, vielleicht ein paar hundert Kandidaten und ein Budget in Stunden oder Tagen, dann ist das Problem mit dynamischer Programmierung (man löst kleine Teilprobleme einmal, merkt sich ihre Ergebnisse und baut die große Lösung daraus zusammen) in Sekundenbruchteilen exakt lösbar. Die „Schwere“ des Problems ist ein theoretisches Grenzverhalten, kein praktisches Hindernis. Und selbst dort, wo die Fälle wirklich riesig werden, liefern Näherungsverfahren garantiert eine gute Lösung. Sogar mit einer beweisbaren Schranke, wie weit man vom Optimum höchstens entfernt ist. Man tauscht dann ein wenig Genauigkeit gegen Geschwindigkeit, bewusst und kontrolliert.

Das ist bemerkenswert: Ein Problem, das die Theorie als „schwer“ einstuft, ist für die Praxis, die uns interessiert, vollständig lösbar. Der Aufwand liegt nicht im Rechnen selbst. Er liegt, wie immer, in und bei den Eingangsdaten dafür.

Wo die Wirklichkeit doch komplizierter wird

Natürlich vereinfacht das Rucksackmodell. Es ist nur ein Anfang und kein Endpunkt. Die Realität bringt zusätzliche Feinheiten mit rein, die aber das Grundprinzip nicht aushebelt, sondern sie machen es sogar noch genauer.

Patches sind nicht immer unabhängig. Manchmal setzt der eine den anderen voraus, manchmal schließen sich zwei gegenseitig aus, manchmal lässt sich ein Bündel nur gemeinsam einspielen. Das sind Kopplungen zwischen den Gegenständen im Rucksack und die Optimierung kann sie auch dementsprechend berücksichtigen. Sie machen das Modell nur etwas umfangreicher. Ebenso gibt es selten nur ein Wartungs- bzw. Patch-Fenster: Über ein Quartal verteilt sich der Aufwand auf viele Wartungsfenster, und die Frage verwandelt sich in: Was in welchem Fenster landen soll. Auch das ist ein wohlbekanntes, lösbares Erweiterungsproblem.

Dazu kommt auch noch: Das Risiko selbst altert. Eine ungepatchte Lücke wird mit der Zeit gefährlicher, weil öffentliche Exploits auftauchen und die Wahrscheinlichkeit der Ausnutzung steigt. Der Wert eines Patches ist damit nicht statisch, sondern wächst, je länger man zuwartet. Wer über mehrere Fenster plant, muss das entsprechend einpreisen und sich fragen: Was heute mehr bringt als in drei Monaten. Nichts davon widerlegt das Grundargument. Es zeigt nur, dass die Optimierung mit der Komplexität mitwachsen kann und muss, während die simple Sortierung nach Schwere an der ersten dieser Feinheiten schon zerbricht.

Woher wir das wissen

Nichts an diesem Argument ist Geschmackssache. Dass „kritisch zuerst“ in unserem Beispiel 100 erreicht und die optimale Auswahl 149, ist kein Meinungsunterschied, sondern ein nachrechenbares Ergebnis. Jeder, der dieselben Zahlen ansetzt, kommt darauf. Dass die Dichte-Heuristik gut ist, aber nicht garantiert optimal ist, ist ein bewiesener Sachverhalt, kein Bauchgefühl. Und dass die Patch-Priorisierung als Modell das Rucksackproblem hat, ist keine Analogie, sondern eine Entsprechung.

Das ist der Punkt: Wer „kritisch zuerst“ verteidigen will, muss nicht mir widersprechen. Er muss der Rechnung widersprechen, an einer präzisen Stelle. Etwa: „In meiner Umgebung sind die Aufwände so verteilt, dass die Reihenfolge nach Schwere zufällig auch das Optimum trifft.“ Das kann sein: Dann zeig mir die Zahlen. Über Zahlen lässt sich reden. Über Bauchgefühle nicht.

„Kritisch zuerst“ fühlt sich verantwortungsvoll an. Ist aber oft nur teuer.

Wie wählt ihr aus, welche Patches ins nächste Wartungsfenster kommen?