Open-Source-Software Sicherer durch weniger Geheimnisse

Software gegen böswillige Angriffe zu schützen, ist extrem schwierig. Dies liegt nicht an einem Zuwenig, sondern an einem Zuviel an Geheimhaltung: Geheime Software lässt sich leichter angreifen. Ein Ausweg aus diesem Dilemma könnte der Einsatz von frei lizenzierter Open-Source-Software sein.

Software spielt in allen komplexen Systemen heute eine entscheidende Rolle. Kommt es zu Pannen, macht man gern »die Software« verantwortlich. So wurden beispielsweise die Startprobleme bei der Inbetriebnahme von Terminal 5 am Flughafen London-Heathrow auf Softwarefehler zurückgeführt. Gleichzeitig aber starteten, flogen und landeten am selben Flughafen hochkomplexe Verkehrsflugzeuge ohne Schwierigkeiten – und das, obwohl sie ohne funktionierende Software wie Steine vom Himmel fallen würden. Wenn man sich also nur genügend Mühe gibt und keine Kosten scheut, dann scheint es möglich zu sein, fehlerfreie Software zu erstellen. Immerhin hat bis heute niemand sein Leben wegen fehlerhafter Flugzeugsoftware verloren; eigentlich keine schlechte Bilanz.

Tatsächlich gibt es gute Techniken, um Bugs zu verhindern. Beispielweise lassen sich »formale« mathematische Methoden anwenden, um festzustellen, ob ein Code fehlerfrei ist. Ein solcher Ansatz wird etwa für »iFACTS«, das Luftverkehrskontrollsystem in Großbritannien verwendet, das auf dem »Spark«-Framework von AdaCore aufbaut. Freilich muss man die vorhandenen Techniken zur Erzeugung fehlerfreier Software, wie sie eben bei Avionik-Software durch verschiedene Sicherheitsnormen vorgeschrieben sind, auch einsetzen.

Allerdings hat sich die Welt durch die Ereignisse des 11. September 2001 und die nachfolgenden Anschläge in London und Madrid verändert. Heute reicht es nicht mehr, nur sicherzustellen, dass Software frei von Fehlern ist, nun darf sie auch keine Ansatzpunkte für Cyber-Attacken bieten. Jede Software, die kritisch ist, ist ein potenzielles Ziel für Angriffe, etwa Software für Systeme, die Kernkraftwerke, Netzverteilernetze oder die Flugsicherung steuern.

Software gegen solche Angriffe zu schützen, ist wesentlich schwieriger, als sie fehlerfrei und damit in einem technischen Sinne sicher zu machen. Kein noch so großer Testaufwand kann zuverlässig angeben, dass eine Software auch vor zukünftigen Angriffsmethoden sicher ist, also auch vor solchen, die erst noch entwickelt werden. Diese werden möglicherweise genau so programmiert, dass sie bestehende Sicherheitstechniken umgehen; ein Angreifer mit großem Know-how wird dabei auch die Möglichkeiten der Testwerkzeuge und -methoden berücksichtigen, um unentdeckt zu bleiben.

Verschleierung verdeckt Designfehler

Ein auf den ersten Blick paradox erscheinender Vorschlag besteht darin, die Geheimhaltung für kritische Systeme und Geräte systematisch zu beseitigen. Heute werden mehr und mehr Geräte von eingebetteten Rechnern gesteuert, die verschleiern, wie das jeweilige System als Ganzes funktioniert. Früher konnte man einen Staubsauger zerlegen, und man wusste, wie er funktionierte: Man sah gleich, ob eine Verdrahtung anfällig war. Unabhängige Tester konnten ein fachlich fundiertes Urteil über die Sicherheit eines Geräts fällen und dafür sorgen, dass unsichere Geräte aus dem Handel genommen wurden. Das ändert sich, sobald Embedded-Computersysteme beteiligt sind. Damit verschwindet die technische Transparenz.

Die Software für solche Systeme wird heute wie selbstverständlich geheim gehalten. Es scheint ganz normal zu sein, dass Unternehmen höchste Geheimhaltung für ihre Produkte anstreben. Die Argumente für den Schutz der eigenen Investitionen und all dessen, was sich unter dem Begriff »geistiges Eigentum« (Intellectual Property) zusammenfassen lässt, scheinen überzeugend. Das Problem aber ist, dass die daraus entstehende Geheimhaltung allzu oft schlampiges Design und schwere Fehler versteckt, welche die Software anfällig für Angriffe machen, und dadurch zu mangelhafter Qualität führt.

Eine derartige Geheimhaltung kann man sich unter Security-Aspekten
heute aber eigentlich nicht mehr erlauben. Nicht nur, weil man sich von einer breiten und unabhängigen Qualitätssicherung abschneidet, sondern auch, weil es ein absolutes Geheimnis ohnehin nicht gibt: Auch die geheimsten Dinge sind immer einigen Personen bekannt. Wenn nur eine kleine Gruppe, die in einem Unternehmen mit der Herstellung von Software befasst ist, Zugang zu diesem Wissen hat, so reicht eine einzige »Schwachstelle«, ein einziger »Bad Guy« – wissentlich oder unwissentlich sei noch dahingestellt –, um die Geheimhaltung infrage zu stellen. Das Geheimnis bleibt zwar weiterhin ein Geheimnis für die meisten, aber es befindet sich zugleich auch schon in den falschen Händen. Was keine angenehme Vorstellung ist, denn diese Bad Guys können nun unter dem Schutzschirm der Geheimhaltung ihr Werk
in aller Ruhe vorantreiben.

Vorteile von Open-Source-Software

Einer der wichtigsten Trends in der Softwareentwicklung der letzten Jahre war der Einsatz von FLOSS (Freely Licensed Open Source Software). Diese Art von Software hat zwei wichtige Eigenschaften: Erstens ist sie frei lizenziert, sodass sie jeder kopieren, verändern und weitergeben kann.

Zweitens sind ihre Quellen frei verfügbar. Man kann sie also gründlich untersuchen und alle Probleme und Schwachstellen, die gefunden werden, offen diskutieren.

Hier ist eine grundsätzliche Veränderung der Sicherheitsphilosophie notwendig: Die Verwendung von FLOSS für kritische Software sollte zumindest wünschenswert, an einigen Stellen sogar verpflichtend sein. Natürlich erleichtert dieses Konzept im ersten Schritt tatsächlich die Arbeit der Bad Guys, doch erfahrungsgemäß sind diese ja sowieso bereit, alles zu tun, um zu den geheimen Dingen vorzudringen. Viel wichtiger aber ist, dass mit FLOSS die weltweite Community der Good Guys sicherstellen kann, dass kritische Software auch den höchsten Sicherheitsanforderungen entspricht. Sie muss sich nun nicht mehr darauf verlassen, dass jemand beim Bewahren der Geheimnisse tatsächlich einen guten Job gemacht hat.

Schließlich kann man auf diese Weise auch sicherstellen, dass die Software mit der besten verfügbaren Technologie erstellt wurde. Wenn man ein Fernsehgerät öffnet und ein Gewirr von falsch isolierten Drähten sieht, würde man einen Defekt vermuten. Die heute in so vielen Geräten enthaltene Embedded-Software ist in viel schlechterem Zustand, das »Gewirr« im Inneren dieser Software, den viel zitierten »Spaghetti-Code«, bekommt bloß niemand zu Gesicht.

Zwei Ansatzpunkte ergeben sich bei der Nutzung von FLOSS für sicherheitskritische Software. Erstens kann man beim Aufbau einer Software von der Verwendung FLOSS-basierter Werkzeuge erheblich profitieren. Eine Möglichkeit, die Softwaresicherheit zu unterlaufen, bietet beispielsweise eine falsche Einstellung des Compilers. Zum Beispiel könnte ein Compiler so eingerichtet sein, dass er nach folgendem Statement sucht:
if Password = Stored_Value then
Dieses wandelt er dann um in:
if Password = Stored_Value
or else Password = „Robert Dewar“
Das wäre natürlich keine sichere Programmierung, und bewusst würde wohl niemand so programmieren – es sei denn, er wollte dafür sorgen, dass »Robert Dewar« unabhängig von Passwortänderungen immer Zugang zum betreffenden System erhält. Aber hier besteht die Schwierigkeit darin, dass man diese Schwachstelle durch noch so genaue Untersuchung der Sourcen der Applikation nicht entdecken kann, denn im Quellcode der Applikation ist das Problem ja überhaupt nicht enthalten. Bei einem in FLOSS programmierten Compiler wäre es ein Leichtes, diese Schwachstelle zu entdecken, weil man hier eben auch den Compiler selbst untersuchen kann.

Ein zweiter wichtiger Punkt ist die Verwendung von FLOSS für den Applikationscode selbst, den dann eine größere Community untersuchen kann. Testexperten können dann Software genauso untersuchen und bewerten, wie sie das früher mit Staubsaugern getan haben. Und sie können Geräte mit unsicherer Software dann ablehnen.

Voneinander lernen

Wie lässt sich dieses Dilemma von Eigentum und Offenheit auflösen? Einerseits müssen die Eigentumsrechte der Unternehmen geschützt werden, sodass weiterhin Anreize zu Innovation bestehen. Aber das darf natürlich nicht zu einer Gefährdung der Öffentlichkeit durch unsichere Software führen. Vielleicht können innovative Formen von Copyright-Schutz auch für Software einen angemessenen Schutz zur Verfügung stellen, auch wenn zu vermuten ist, dass dieser Schutz in den meisten Fällen nicht wirklich nötig ist.

Angenommen Boeing wäre gezwungen, die Softwaresteuerung seiner neuen 787-Dreamliner offenzulegen. Würde das Airbus einen Vorteil verschaffen? Vermutlich nicht, weil man die 787-Avionik sowieso nicht einfach in einen Airbus 350 übernehmen kann (Bild 1). Wahrscheinlich könnte Airbus durch das Studium der Boeing-Software ein paar nützliche Dinge herausfinden, so wie man nützliche Dinge sieht, wenn man sich die Hardware und das Design der Boeing-Maschinen anschaut. Wenn aber alle gezwungen sind, ihre Software offenzulegen, könnte dadurch ein Prozess des Voneinander-Lernens entstehen, von dem Wettbewerb und Innovation schließlich profitieren.

Über praktikable und allgemein akzeptable Lösungen wird man noch weiter nachdenken müssen. Aber sicher ist auch: Einfach auf dem derzeitigen Weg weiterzugehen, ist nicht möglich. Die Welt wird immer gefährlicher, und die zunehmende Verwendung von »geheimer« Software, die schlecht konzipiert und anfällig ist, steigert die Gefahren. Es müssen Wege gefunden werden, diesen Gefahren zu begegnen. Mehr Offenheit kann eine wesentliche Voraussetzung dafür sein.

Über den Autor:

Robert Dewar ist Mitgründer und Präsident von AdaCore.

Vertragsbasierte Programmierung in »Ada« 
Zu den Methoden, die Software zuverlässiger zu machen, gehört die »Vertragsbasierte Programmierung«. »Ada« ist eine Programmiersprache, bei der dieses Konzept zum Sprachstandard gehört. In der vertragsbasierten Programmierung wird das Vertragskonzept des Geschäftslebens analog auf die Software angewendet. In Ada sind Operationen parametrierbare Unterprogramme (Prozeduren oder Funktionen), Vor- und Nachbedingungen fungieren als »Vertragsbedingungen« und werden durch boolesche Ausdrücke, die zur Deklaration des Unterprogramms gehören, ausgedrückt. Einer der wichtigsten Vorteile der vertraglichen Vor- und Nachbedingungen ist, dass sie die Semantik der jeweiligen Operation definieren: Was die Operation von ihren Parametern erwartet und was sie als Ergebnis berechnen soll. In den meisten Sprachen würde man diese Informationen durch Kommentare an den Code anheften. Bei vertragsbasierter Programmierung gehört das hingegen zur Syntax. »Ada 2012«, die neueste Version der Programmiersprache, erlaubt daher eine Verifizierung der Vor- und Nachbedingungen in mehrfacher Hinsicht:

■ Zur Laufzeit erfolgt ein Check, der sicherstellt, dass die Voraussetzungen, sowohl die Vorbedingung bei der Parameterübernahme als auch die Nachbedingung bei der Ergebnisübergabe, erfüllt sind. Bei Verletzung dieser Bedingungen wird eine Exception ausgelöst.

■ Die Überprüfung kann durch Tools erfolgen, die durch formale statische Analyse ermitteln, ob die Vorbedingungen bei jedem Aufruf erfüllt werden und dass die Nachbedingungen basierend auf der Definition der Operation eingehalten werden.

■ Eine manuelle Codeüberprüfung kann durchgeführt werden, wenn der Check zur Laufzeit nicht möglich ist. Doch auch in diesem Fall lässt sich die Standardsyntax, die eine Quantifizierung unterstützt, mit geeigneten Tools analysieren.

Ada 2012 unterstützt die vertragsbasierte Programmierung, die entsprechenden Anforderungen sind in die bestehenden Datentypen und das Unterprogramm-Framework integriert. Damit lassen sich umfassende Checks statisch oder dynamisch durchführen. Mit der wachsenden Rolle von Software in kritischen Bereichen wird die Möglichkeit, vertragliche Bedingungen direkt im Quellcode auszudrücken, immer wichtiger. Ada 2012 bietet dafür eine effektive Lösung. 

Was verbirgt sich hinter der Programmiersprache Ada? 

Ada ist eine strukturierte Programmiersprachen mit statischer Typenbindung und gilt als erste standardisierte Hochsprache. Sie wurde von Jean Ichbiah bei Honeywell Bull in den 1970er Jahren entworfen. Vom Erscheinungsbild ähnelt Ada der Programmiersprache Pascal und ist genauso wie Modula-2 als Wirthsche Sprache zu betrachten. Ebenso wie Modula ist Ada aber auch strenger in der Programmierung als Pascal.

Herausragende Merkmale von Ada sind etwa das strenge Typsystem (starke Typisierung), zahlreiche Prüfungen zur Programmlaufzeit, Nebenläufigkeit, Ausnahmebehandlung und generische Systeme.

Ada-Compiler können sich einem standardisierten Test (Validierung) unterziehen, der praktisch Grundvoraussetzung für den professionellen Einsatz ist. Aufgrund der hohen Anforderung, die validierte Compiler erfüllen müssen, hat sie sich vor allem in sicherheitskritischen Bereichen durchgesetzt, zum Beispiel in der Flugsicherung, in Sicherheits-Einrichtungen der Eisenbahn, in Waffensys­temen, der Raumfahrt, der Medizin oder der Steuerung von Kernkraftwerken. Benannt wurde die Sprache nach Lady Ada Lovelace (1815–1852), der Tochter von Lord Byron und Mitarbeiterin von Charles Babbage. Die richtige Schreibweise ist daher Ada und nicht, wie gelegentlich verwendet, ADA. Wegen ihrer schriftlichen Kommentare zur mechanischen Rechenmaschine »Analytical Engine« wird Ada Lovelace auch als erste Programmiererin bezeichnet.