Was wir aus Heartbleed lernen könnten

Von Thomas Bez am 14.04.2014 im Weblog Tedesca <http://www.tedesca.net>


Nachlässigkeit und Disziplin

Wie kann es sein, daß ein junger Bursche die Sicherheit des gesamten Internet aushebelt?

Es gibt Programmierfehler, die Leute trotz und zuweilen wegen aller Klugheit machen, Denkfehler eben. Und es gibt ausgesprochen dumme Fehler, die aus der Vernachlässigung der Pflicht zu bedenken, was man gerade tut, resultieren. Eine Speicherkopieroperation, die durchgeführt wird ohne den Anfangszeiger und die Länge des Kopierbereiches genau zu prüfen, ist solch ein dummer Fehler. Das sollte man einmal gelernt haben, sofern man die Grundlagen gelernt hat. Aber wer am Silvesterabend 2011 nichts besseres zu tun hat als die Heartbeat-Funktion fertig zu programmieren und für die Veröffentlichung freizugeben, sollte erst noch mal einen Blick ins Leben tun statt das Internet fahrlässig kaputt zu machen.

Wir nennen es also Nachlässigkeit und unterstellen nicht, daß der Entwickler von der NSA gekauft wurde, aber ausschließen kann man das auch nicht. Es ist auch absolut irrelevant, denn daß die NSA für Hintertüren bezahlt, ist bereits bekannt, und daß sie diese Sicherheitslücke von Anfang an genutzt haben muß, werden wir gleich darlegen. Zuvor aber noch ein paar Überlegungen, was für Umstände solchen Programmierer-Nachlässigkeiten Vorschub leisten. Die oft gehörte Diskussion um Wert oder Unwert der Sprache C, die Pufferüberläufen und falschen Speicherzugriffen tatsächlich Vorschub leistet, ist zwar nicht unberechtigt, verfehlt aber das Thema. Auch in C kann man diszipliniert programmieren.

Als wir in den 1980er Jahren Informatik studierten, war es noch nicht allgemein üblich, bereits mit gewissen Programmierkenntnissen die Ausbildung zu beginnen. So spielte das Handwerkliche am Anfang des Studiums noch eine beträchtliche Rolle. Und dieses Handwerk wurde am Beispiel längst vergessener Sprachen wie Pascal, Modula und gar Ada vermittelt. Solche streng typisierten Sprachen haben einen wichtigen didaktischen Effekt, denn sie zwingen zu Disziplin im Durchdenken eines Problems wie in der programmatischen Umsetzung. Auch nach unserem Umstieg auf die Sprache C, die nun einmal zum Standard geworden ist, was man akzeptieren muß, war unser Bewußtsein dafür geschärft, was man in C anrichten kann, wovor einen andere Sprachen von Hause aus besser schützen.

Typische Fehler

Worin bestand der Heartbleed-Fehler nun? In der Funktion tls1_process_heartbeat wird eine vom Angreifer gemeldete Payload-Länge kritiklos übernommen:

hbtype = *p++;
n2s(p, payload);
pl = p;

und danach werden die vermeintlichen Daten in die Antwortnachricht kopiert:

buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);

Der eigentlich empfangene Datenpuffer ist jedoch viel kürzer. Daher lautet die Korrektur:

hbtype = *p++;
n2s(p, payload);
if (1 + 2 + payload + 16 > s->s3->rrec.length)
    return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;

Es überrascht nicht besonders, daß sich hier gleich drei typische Programmierfehler treffen:

  • Feldgrenzen nicht prüfen
  • Eingabewerte nicht auf Wertevorrat, Format und/oder Plausibilität prüfen
  • uninitialisierte Variable oder Pufferspeicher verwenden

Wir wollen uns aber hier nicht über einen armen Entwickler lustig machen. Qualitätssicherung ist dafür da, Fehler zu eliminieren, und um Qualitätssicherung soll es hier gehen.

Code Review

Fehler wie diese kann ein geübter Code Reviewer bereits durch Betrachten des Codes finden. Ein Aufruf von memcpy ist ein Signal, daß man hier besonders genau hinsehen muß. Und wenn sie der erste Reviewer nicht findet und der zweite auch nicht, dann ist es vielleicht der zehnte. Solche Suche ist durchaus sinnvoll, bevor richtig getestet wird, es kostet halt scheinbar ein wenig mehr.

In den IT-Abteilungen der Industrie, zumindest der Industriezweige, die eine regulatorische Verpflichtung auf Sicherheit haben, herrschte ab dem Morgen des 8. April große Hektik. Erst einmal alle betroffenen Systeme identifizieren, Hunderte oder gar Tausende von Servern patchen, neue Zertifikate bereitstellen, das alles mit den Eigentümern der Anwendungen koordinieren... Der Zirkus wird noch ein paar Tage gehen. Wieviel das wohl kostet? Hätten Unternehmen dieses Geld in ihre IT besser investieren können?

(Ironischerweise sind in diesem Fall Unternehmen besser dran gewesen, die ihre Systemsoftware nicht so oft aktualisieren. Das kann aber nicht als Regel gelten. Zumal es nicht die Regel sein sollte, mit der Aktualisierung zwei Jahre zu warten, und das war im Fall von Heartbleed die Zeitspanne, die auch durchaus länger hätte ausfallen können.)

Die NSA beschäftigt garantiert Code-Reviewer in großer Zahl, die für nichts anderes bezahlt werden und auf nichts anderes gedrillt sind als solche Fehler zu finden. Auch Unternehmen, die Exploits sammeln und verkaufen, suchen bestimmt jede Änderung in sicherheitskritischer Software ab, also im Betriebssystem (zum Beispiel Linux), Systembibliotheken (zum Beispiel OpenSSL), Middleware (zum Beispiel OpenVPN) oder sicherheitskritischen Anwendungen (zum Beispiel Apache). Am 1. Januar 2012 wurde OpenSSL mit dem Heartbleed-Fehler veröffentlicht und wir wetten, daß diejenigen, die von unveröffentlichten Fehlern am meisten profitieren, ihn im Februar schon kannten. Diese Leute sind zu schlau, um nicht längst diese wundervolle Methode Angriffsvektoren zu sammeln entdeckt zu haben.

Open Source

Mit Open Source geht das besonders einfach und günstig, weil jeder die Software bekommen kann und jede Änderung im Detail herausfinden kann. In dieser Hinsicht ist Open Source noch deutlich verwundbarer als proprietäre Software, deren Quellcode nie an die Öffentlichkeit kommt. Dazu kommt die immer größere Verbreitung. Bald wird sich ein Angriff auf Open Source noch mehr lohnen als ein Angriff auf Windows.

Das ist kein Argument gegen Open Source. Open Source gibt allen, die das wollen, die Möglichkeit, Fehler zu finden. Die Anwender verlassen sich aber zu sehr auf Open Source. Es steht ja vermeintlich eine große Gemeinde dahinter, die jede Zeile Code fünfmal rumdreht, bevor sie sie freigibt. Irrtum – es stehen immer weniger dahinter, als man denkt.

Die Wahrheit ist doch: Kaum ein Mensch in der Open Source-Gemeinde außer dem Autor sieht sich ein Stück Code noch einmal genauer an, sofern es nicht ein aufsehenerregendes neues Kernel-Feature betrifft. Warum sollte das auch jemand tun? Etwas Eigenes zu schreiben macht Spaß und man kann sich damit einen Namen machen, sogar außerhalb der Gemeinde, wenn man sehr gut ist. Wozu sollte sich auch jemand fremden Code ansehen, da es schließlich nicht bezahlt wird und schon garnicht Aufmerksamkeit und Ehre einbringt. So kann ein katastrophaler Fehler zwei Jahre überleben.

Die Hersteller von kostenbewehrten Distributionen wie Red Hat oder SuSE haben hier noch schwerer versagt, denn sie sind an diesem Geschäft mit finanziellen Interessen beteiligt. Ein Fehler dieser Größenordnung in einer kommerziellen Distribution sollte die Frage aufwerfen, warum man hier jemanden für etwas bezahlt, was dieser auch nur umsonst bekommen und offensichtlich nicht verbessert hat.

Die Verantwortung der Industrie

Wir haben gesehen: Auf der Produzentenseite von Open Source sitzen nicht die Leute, die von intensiver Qualitätssicherung profitieren. Das ist nicht verwerflich, sondern hat schlichte ökonomische Gründe. Die Benutzerseite muß hingegen, statt viel schönen Code schön kostensparend (nämlich für lau) einzusetzen, in Qualitätssicherung investieren.

Der private Linux-Anwender hat keine Chance, vor jedem Update die Software zu prüfen, die zu installieren er im Begriff steht. Wer sich Linux statt Windows auf seinem PC installiert, riskiert dabei auch nicht viel. Und ob vielleicht eine Milliarde Facebook-Paßworte kompromittiert wurden oder die Email-Paßworte einer halben Nation von GMX- oder Googlemail-Benutzern, ist auch von geringer Relevanz. Eine Industrie aber, die von der Sicherheit ihrer Informationen abhängt, ob Maschinenbau oder Finanzindustrie, dürfte es sich nicht erlauben, Open Source-Software ungeprüft in die Produktion zu übernehmen. Das könnte eines Tages als Verletzung von Sorgfaltspflichten angesehen werden.

Wenn Unternehmen, die untereinander nicht im Wettbewerb um Softwaresicherheit stehen, dabei kooperieren würden, wären die Mehrkosten für die Beteiligten sogar marginal, der Gewinn an Sicherheit aber enorm. Heartbleed könnte der Anfang eines Umdenkens in der Industrie sein, und das wäre uns allen zu wünschen.

Umsonst gibt es nichts.