Taint – also fehlerhafte Daten – kann auf unerwartete Weisen durch ein Programm fließen, so dass ein automatisiertes Tool unter Umständen auch eine wichtige Rolle für das Verstehen dieser Kanäle spielt. CodeSonar visualisiert die Quellen und Senken der Fehler, und im Fluss involvierte Programmelemente können über eine reguläre Codeansicht gelegt werden. Das erleichtert es den Entwicklern, die Risiken ihres Codes zu verstehen und zu entscheiden, wie der Code am besten verändert werden soll, um die Schwachstelle zu schließen.
Im nächsten Beispiel, in Bild 2, gibt es in Zeile 80 eine blaue Unterstreichung. Sie bedeutet, dass der Wert der Variablen, die hier als Parameter eingelesen wird, durch das Dateisystem beschädigt sein könnte. Obwohl das einem Anwender hilft, den Code zu verstehen, sind die interessantesten Teile der Warnung in Zeile 91 und 92 zu finden: Die Unterstreichung in Zeile 91 zeigt, dass es sich beim zurückgegebenen Wert von compute_pkgdatadir() um einen Pointer auf Daten handelt, die von der Umgebung beschädigt wurden. Der Aufruf strcpy() kopiert diese Daten dann in den lokalen Pufferspeicher (angeführt in Zeile 84). Das überträgt die Eigenschaft der Fehlerhaftigkeit in diesen Pufferspeicher. Als logische Folge zeigt in Zeile 92 die rote Unterstreichung, dass der Pufferspeicher einem fehlerhaften Wert aus der Umgebung ausgesetzt wurde.
Die Visualisierung des Buffer Overrun bestätigt, dass der zurückgereichte Wert von compute_pkgdatadir() tatsächlich ein Wert ist, der aus einem Aufruf an getenv() abgerufen wurde. Ein Entwickler, der diesen Wert untersucht, kann somit sehen, dass eine Schwachstelle besteht, wenn ein Angreifer den Wert der Umgebungsvariablen manipuliert. Bei CodeSonar liefert die Top-Down-Darstellung eine Alternative, um den Fluss fehlerhafter Daten durch das Programm zu betrachten (Bild 3).
In diesem Beispiel identifiziert die rote Farbe ein Modul mit fehlerhaften Quellen; die blaue zeigt fehlerhafte Senken. Es ist eine vernünftige Annäherung an die Angriffsoberfläche eines Programms. Der Code innerhalb dieses Moduls ist im Ausschnitt auf der rechten Seite ersichtlich; die Unterstreichung zeigt die Variablen mit fehlerhaften Daten.
Software, die voraussetzt, dass ihre Inputs gut entwickelt und annehmbar sind, ist grundsätzlich riskant und fehleranfällig. Mit der Taint-Analyse lernen Programmierer zu verstehen, wie riskante Daten von einem Teil des Programms in den nächsten fließen. Hoch entwickelte statische Analyse-Tools können Taint-Analysen ausführen und die Ergebnisse dem Anwender aufzeigen. Sie sind hilfreich, weil sie Fehler auffinden, die nur unter ungewöhnlichen Umständen und sehr früh in der Entwicklung auftreten. Bevor der Code überhaupt zum Testen fertig ist, kann sich die Investition bereits lohnen. Sie sollen keine traditionellen Testmethoden ersetzen, sondern sie vielmehr ergänzen.
Die drei wichtigen Kategorien von Fehlern |
Fehler, die grundlegende Laufzeit-Regeln missbrauchen und zu einem undefinierten Programmverhalten führen. Dazu zählen Speicherfehler wie Null Pointer Dereferences und Buffer Overruns, Nebenläufigkeitsfehler wie Data Races und viele andere (z.B. Nutzung von uninitialisiertem Speicher). Fehler durch regelwidrige Nutzung von Standard-APIs. Beispielsweise spezifiziert die C Library nicht, was passiert, wenn derselbe Deskriptor zweimal geschlossen wird. Weil dies keinen Sinn ergibt, ist es wahrscheinlich auf einen Fehler zurückzuführen. In diese Kategorie gehört auch die Verknappung begrenzter Ressourcen, z.B. durch Speicherfragmentierung (Memory Leaks) oder an Deskriptoren. Unstimmigkeiten oder Widersprüche im Code. Sie müssen nicht zum Programmabsturz führen, aber sind ein Indiz dafür, dass der Programmierer wahrscheinlich eine wichtige Codeanlage missverstanden hat. Beispielsweise deutet eine Bedingung, die immer richtig oder immer falsch ist, darauf hin, dass dies so nicht beabsichtigt war, weil es zu totem Code führt. |
In diesem Beispiel identifiziert die rote Farbe ein Modul mit fehlerhaften Quellen; die blaue zeigt fehlerhafte Senken. Es ist eine vernünftige Annäherung an die Angriffsoberfläche eines Programms. Der Code innerhalb dieses Moduls ist im Ausschnitt auf der rechten Seite ersichtlich; die Unterstreichung zeigt die Variablen mit fehlerhaften Daten.
Software, die voraussetzt, dass ihre Inputs gut entwickelt und annehmbar sind, ist grundsätzlich riskant und fehleranfällig. Mit der Taint-Analyse lernen Programmierer zu verstehen, wie riskante Daten von einem Teil des Programms in den nächsten fließen. Hoch entwickelte statische Analyse-Tools können Taint-Analysen ausführen und die Ergebnisse dem Anwender aufzeigen. Sie sind hilfreich, weil sie Fehler auffinden, die nur unter ungewöhnlichen Umständen und sehr früh in der Entwicklung auftreten. Bevor der Code überhaupt zum Testen fertig ist, kann sich die Investition bereits lohnen. Sie sollen keine traditionellen Testmethoden ersetzen, sondern sie vielmehr ergänzen.
Der Autor
Dr. Paul Anderson |
---|
leitet die Entwicklungsabteilung bei GrammaTech (USA), einem Hersteller von statischen Codeanalyse-Tools. Dr. Anderson hat über 20 Jahre Erfahrung in der Entwicklung von statischen Analysewerkzeugen und automatisierten Test Tools. Er besitzt einen Hochschulabschluss (Bachelor of Science) des King‘s College, Universität London und einen Doktortitel der City University London. Seine Arbeit findet Erwähnung in zahlreichen Artikeln, Buchkapiteln und auf internationalen Konferenzen. |
sales@grammatech.com