aufmacher-layout-2.jpg

Hitex

Software-Sicherheit und -Qualität sind Herausforderungen, denen sich nicht nur die IT-Abteilung, sondern jeder Embedded-Entwickler und letztlich das gesamte Unternehmen stellen muss. Dies gilt besonders für Branchen wie die Automobil- und Luftfahrtindustrie, Militär und Humanmedizin, wo schon geringe Software-Mängel gravierende Folgen haben können:

  • 2014 musste Toyota wegen eines Programmierfehlers weltweit 2,1 Millionen Fahrzeuge des Typs Prius zurückrufen, da die Gefahr bestand, dass das Auto während der Fahrt stehen bleibt.
  • Ebenfalls 2014 wurde der Heartbleed-Bug bekannt: Eine Lücke in der OpenSSL-Bibliothek ermöglichte es Angreifern, persönliche Daten auszulesen. Zahlreiche Onlinedienste, Websites und Geräte wie VoIP-Telefone und Router weltweit waren betroffen.

Diese Beispiele verdeutlichen, wie wichtig zuverlässige, sichere Software ist. Zwei Sicherheitsaspekte kommen zum Tragen:

  • Safety, also funktionale Sicherheit: Vom System darf keine maßgebliche Gefahr für Mensch und Umwelt ausgehen (vergleiche Beispiel Toyota).
  • Security, also Datensicherheit: Das System ist gesichert gegen böswillige Einflüsse und Manipulationen von außen (vergleiche Beispiel Heartbleed).

Um die – funktionale – Sicherheit von sicherheitskritischen Systemen zu gewährleisten, haben anerkannte Organisationen verbindliche Software-Normen entwickelt, darunter den allgemeinen Standard IEC 61508 und die daraus abgeleitete Norm ISO 26262 für die Automobilbranche. Beide Regelwerke definieren Sicherheitsanforderungsstufen (SIL, Safety Integrity Level) als Maß für die geforderte oder erreichte risikomindernde Wirksamkeit von Sicherheitsfunktionen.

Qualitätssicherung beim Programmieren

Bei sicherheitskritischer Software kommt es darauf an, potenzielle Sicherheitslücken und Programmierfehler so früh wie möglich zu erkennen und zu bereinigen, das heißt schon bei der Entwicklung, nicht erst beim Testen. Je eher man Mängel und Risiken behebt, desto geringer sind deren Auswirkungen.

Eckdaten

Jedes nichttriviale Programm ist fehlerhaft, sagt eine alte Weisheit der Software-Welt. Das gilt auch für sicherheitskritische Anwendungen. Da kein Entwickler jede Facette moderner komplexer Software durchdringen kann, helfen automatisierte Tools zur statischen Code-Analyse, schon beim Schreiben Schwachstellen aufzuspüren. Denn je früher man einen Fehler findet, desto einfacher und schneller lässt er sich beheben.

Programmierstandards wie Misra für C und C++ bieten dem Entwickler Orientierungshilfe und unterstützen ihn darin, hochwertigen, zuverlässigen Code zu schreiben. Ursprünglich für den Automobilsektor geschaffen, wird Misra heute branchenübergreifend für sicherheitskritische Systeme genutzt. Der Standard soll helfen, Defizite im Code schon am Quelltext zu erkennen, um Laufzeitfehlern vorzubeugen. Beispielsweise sind unklare Sprachkonstrukte, Pointer-Arithmetik, Rekursionen und verschachtelte Kommentare tabu. Damit adressiert Misra einen weiteren Aspekt von Software-Qualität: den Programmierstil, das heißt die Verständlichkeit, Testbarkeit, Wartbarkeit und Änderungsfreundlichkeit des Codes.

Defiziten auf der Spur

Mit statischer Code-Analyse (SCA) lassen sich Sicherheitslücken, Fehler und Mängel im Quellcode schon vor der Kompilierung aufspüren und beheben. Für sicherheitskritische Systeme ist SCA vorgeschrieben. Leistungsfähige Tools prüfen den Quelltext auf:

  • Sicherheitsrisiken wie Pufferüberläufe oder Speicherzugriffsverletzungen
  • Einhaltung von Programmierstandards wie Misra
  • Lexikalische, syntaktische, semantische und logische Fehler
  • Schwächen im Programmierstil

Diese Prüfungen lassen sich kaum manuell bewältigen. Anwendungen und Programmteile sind komplex, voneinander abhängig und von so vielen Regeln bestimmt, dass auch die besten Entwickler nicht in der Lage sind, ihren Code vollständig zu überblicken. Die Software in modernen Automobilen beispielsweise erreicht leicht einen Umfang von über 100 Millionen Lines of Code. Entwickler brauchen deshalb Tools, die sie bei der statischen Code-Analyse unterstützen.

Tool-Landschaft

Die derzeit verfügbaren SCA-Werkzeuge erkennen neben formalen Fehlern, Richtlinienverstößen und potenziellen Sicherheitslücken auch schlecht strukturierten Code. Zum Beispiel finden sie: fragwürdige Konstrukte, mögliche Deadlocks, Race-Conditions und Speicherlecks, nicht eingehaltene Bereichsgrenzen und Größen, undefinierte Ausdrücke, Endlosschleifen, mehrfach verwendeten (duplicated) Code.

Stand-alone oder in die Entwicklungsumgebung integriert, stellen die Tools auch Metriken zur Software-Qualität bereit. Diese reichen von einfachen Statistiken wie Lines of Code (Anzahl Programmzeilen) oder die Größe einer Klasse bis zu berechneten Kennzahlen für die Komplexität oder die Wartbarkeit des Codes. Die Metriken erlauben weitergehende Analysen, Vergleiche, Bewertungen und Vorhersagen, zum Beispiel für Aufwands- und Risikoschätzungen oder für Fehlerprognosen.

Mythen der SCA

Auch wenn Tools zur statischen Code-Analyse ihre Nützlichkeit längst bewiesen haben – vier Mythen der automatisierten Statischen Code-Analyse halten sich hartnäckig.

Bild 1: Der Compiler entdeckt eine nicht initialisierte Variable.

Bild 1: Der Compiler entdeckt eine nicht initialisierte Variable.Hitex

Mythos 1: Tools zur statischen Code-Analyse sind bessere Compiler. Tatsächlich erkennen auch moderne Compiler Codefehler, beispielsweise nicht initialisierte Variablen. Dies allerdings nur innerhalb von Dateien und Funktionen. SCA prüft tiefergehend und findet auch komplexere Probleme und Abhängigkeiten, und zwar programmübergreifend und systemweit.

Das Beispiel in Bild 1 zeigt einen typischen Fehler, den ein Compiler finden kann. Hier wird auf die potenziell uninitialisierte Variable „closingTag“ hingewiesen. Bild 2 zeigt dagegen ein Beispiel für eine mögliche Null-Pointer-Dereferenzierung. Diesen Fehler konnte nur die SCA mit ihrer umfassenden Perspektive aufdecken. Die Variable „document“, die der Rückgabewert der Methode „GetDocument()“ ist, kann möglicherweise in Zeile 980 dereferenziert werden, obwohl sie den Wert „NULL“ enthält. In den anderen beiden Codezeilen kann das nicht passieren, denn sie prüfen vorab den Wert von „document“.

Bild 2: Das SCA-Tool entdeckt auch eine mögliche Null-Pointer-Dereferenzierung.

Bild 2: Das SCA-Tool entdeckt auch eine mögliche Null-Pointer-Dereferenzierung.Hitex

Mythos 2: Nur unerfahrene Entwickler brauchen SCA-Tools. Fakt ist: Mit statischer Code-Analyse arbeiten alle Entwickler effizienter. In komplexen Programmen, vor allem in Alt- und Fremdanwendungen, ist es meist schwierig, vorhandene Sicherheitslücken, Fehler und Regelverstöße zu finden. Probleme können aus verschachtelten, tief verborgenen Funktionen und Modulen stammen, deren Code der Entwickler nicht kennt. SCA-Tools entdecken Fehler über mehrere Ebenen hinweg und enthalten Prüfmechanismen auch für nebenläufige Prozesse. Dies ist auch für die erfahrensten Entwickler wertvoll. So spüren SCA-Werkzeuge beispielsweise auch Cross-Site-Scripting-Risiken im Code auf – die ohne Tool schwer erkennbar sind.

Falsche Fehler

Mythos 3: SCA-Tools liefern zu viele falsch-positive Ergebnisse. In Wahrheit fangen Tools zur statischen Code-Analyse überwiegend tatsächliche Probleme ab – manche Funde sind nur scheinbar falsch-positiv. Als falsch-positiv bezeichnet man Testergebnisse, die das Testkriterium fälschlicherweise als erfüllt anzeigen. Hersteller von SCA-Werkzeugen fokussieren sich zunächst auf die Minimierung falsch-negativer Ergebnisse, damit die Tools keine wichtigen Fehler und Schwachstellen übersehen. „Eine Falsch-Positiv-Rate von 0 sollte nicht das Ziel sein“, erklärt aber Mark Grice, SCA-Experte bei Rogue Wave Software. „Eine sehr niedrige Falsch-Positiv-Rate ist in der Regel mit einer hohen Falsch-Negativ-Rate verknüpft. Es ist einfacher und prinzipiell empfehlenswert, falsch-positive Ergebnisse zu managen, statt falsch-negative. Letztere zeigen ihr hässliches Gesicht oft erst, wenn die Software im Einsatz ist.“

Gute SCA-Tools bieten nicht nur intelligente Analysefunktionen, sondern lassen sich auch an individuelle Sicherheits- und Programmierstandards anpassen. Sie berücksichtigen Vorgaben für unterschiedliche Arten von Code und erlauben es, einzelne Segmente von Prüfungen auszuschließen. So kann der Anwender die Anzahl der falsch-positiven Ergebnisse reduzieren und quasi das Tool überstimmen.

Mythos 4: Das Test- oder QS-Team ist dafür zuständig, vorhandene Fehler im Code zu finden; viele Entwickler meinen, es sei am effizientesten, den erstellten Code von einem anderen Team prüfen zu lassen. Sie selbst bräuchten daher kein Analysetool. Gegen diese Ansicht spricht: 80 % der Fehler und Schwachstellen von Software entstehen bei der Programmierung. Deshalb ist es effizienter, die Probleme direkt an der Quelle zu beheben, statt sie zu verlagern und zusätzliche Mitarbeiter und Prozesse zur Problemlösung einzubinden.

Nach Capers Jones – einem bekannten amerikanischen Spezialisten für Software-Engineering – steigt der Aufwand für die Bereinigung von Codemängeln umso stärker, je später im Entwicklungszyklus die Bereinigung erfolgt: von 15 Minuten in der Implementierungsphase auf 25 Stunden im Produktivbetrieb.

Strengthen Your Code

Automatisierte statische Code-Analyse erkennt einfache Fehler, komplexe Probleme, Regelverstöße und Sicherheitslücken im Code sehr früh – auch Mängel, die beim Testen nicht auffallen. Die Fehlerbehebung wird vereinfacht und beschleunigt, der Testaufwand reduziert. Daraus resultieren kürzere, effizientere und kostengünstigere Entwicklungszyklen und zugleich zuverlässiger, sicherer, standardkonformer (zertifizierungsfähiger) Code. Last but not least: Mit automatisierter SCA können Entwickler sich auf die Kundenanforderungen und die funktionale Güte ihrer Software konzentrieren, was die Codequalität weiter und entscheidend erhöht.

Infokasten

Das Werkzeug Klocwork von Rogue Wave Software stellt alle im Artikel beschriebenen Funktionen für die statische Code-Analyse bereit. Zusätzlich bietet es:

  • Misra-Konformitätsprüfungen
  • Datenflussanalyse, auch projektübergreifend
  • Definition eigener Sicherheits-, Zuverlässigkeits- und Compliance-Prüfungen
  • Trendermittlung für Software-Metriken
  • Reporting per Drag and Drop
  • Refactoring

Klocwork ist IEC-61508- und ISO-26262-zertifiziert und eignet sich für sicherheitskritische Software-Entwicklungen bis SIL 3 (IEC 61508) und ASIL D (ISO 26262). Das Tool analysiert den Quellcode „on the fly“, das heißt während der Entwickler den Code erfasst. Die gefundenen Fehler und Mängel werden markiert und erläutert, sodass der Entwickler sie sofort korrigieren kann. Das Ergebnis wird ihm wiederum direkt zurückgemeldet. Klocwork unterstützt die Programmiersprachen C, C++, C# und Java.