Parasoft
Mehr Software-Safety und -Security durch Codierstandards
Software dringt in Produkte, Geräte und Bereiche vor, bei denen es unmöglich schien. Entwickler müssen sich intensiv mit der Software in diesen Produkten und den daraus resultierenden Folgewirkungen beschäftigen und Blickwinkel eines Ingenieurs annehmen: Engineering ist gefragt.
Qualitativ schlechte Software ist teuer, denn die Fehlerbeseitung verursacht Mehrkosten. Die meisten Software-Defekte werden vom Programmierer verursacht, der sie in das Produkt einbringt. Schaffen wir es, dass beim Entwickeln von Software keine Fehler zu machen, kann Software zu deutlich geringeren Kosten entwickelt werden. Der Forscher Capers Jones führt jährlich eine Studie zum Thema Softwarekosten durch. Wie die Daten zeigen, steigen die typischen Kosten für Software mit jeder Phase an – vom Erstellen des Pflichtenhefts über das Programmieren bis zur Wartung. Die Art und Weise wie Teams an Qualität herangehen, bestimmt, ob ihr Prozess gesund oder ‚pathologisch‘ ist.
Die Kosten mangelnder Qualität
Werden Defekte sofort beim Schreiben des Codes gefunden, sind die Kosten relativ niedrig (Bild unten). Kann man 85 % aller Defekte schon in der Entwicklungsphase beseitigen, wirkt sich dies markant auf die Kosten aus. Laut Untersuchungen an realer Software in Unternehmen kostet das Beheben von Fehlern nach der Freigabe etwa 16.000 US-Dollar u. U. deutlich mehr (siehe Bild Seite 2). Erfolgen die Qualitäts- und Security-Maßnahmen durch Tests am Ende des Entwicklungszyklus und damit unmittelbar vor Freigabe, erhöhen sich Aufwand und Kosten etwa um den Faktor 15 gegenüber dem Auffinden in frühzeitigen Security-Audits. Warum aber glauben wir, bei Software kann man Qualität und Sicherheit ‚hineintesten‘?
Folgenden Erkenntnisse weisen darauf hin, dass nahezu niemand ingenieurmäßig an die Software-Entwicklung herangeht:
• Was die meisten Entwickler tun, ist nicht reproduzierbar: Zwei Entwickler lösen dieselbe Aufgabe mit unterschiedlichen Ergebnissen.
• Es fehlt an gut ausgearbeiteten ‚Best Practices‘: Software-Entwickler betrachten Codierstandards als ein Regelwerk, auf dessen Einhaltung die Teamleitung besteht, und verkennen dabei, dass ein Codierstandard Wissen, Praxis und Erfahrung verkörpert. Während einem Elektroingenieur klar ist, dass Standards eine Möglichkeit sind, ein auf Anhieb sicheres Produkt zu bauen, sieht ein Software-Entwickler dagegen in einem Standard eine Restriktion, die ihn hemmt – ein ‚False Positive‘ also.
• Uneinheitliche Entwickler-Schulungen: Die Ausbildung im Bereich der Software-Entwicklung erfolgt nicht so standardisiert wie bei den Ingenieurwissenschaften. Oft liegt der Fokus auf Programmiersprachen anstelle von Standards und etablierten Praktiken.
Mehr Safety und Security
Die Grafik von Caspers Jones zeigt die durchschnittlichen Kosten zum Beheben von Fehlern in den einzelnen Entwicklungsabschnitten auf.
© ParasoftCodierstandards haben das Ziel, bewährte Programmierpraktiken zu etablieren, mit denen sich funktional sicherer, zuverlässiger, prüfbarer und pflegbarer Code erstellen lässt. In der Regel bedeutet das, unsichere Programmierpraktiken ebenso zu vermeiden wie Code, der zu unvorher-sehbarem Verhalten führen kann.
In der vergangenen Dekade gab es bei den Werkzeugen wie statische Analysetools, zum Beispiel C/C++test von Parasoft, eine Verlagerung: Anstelle der Aufdeckung von potenziell problematischem, unsicherem Code oder bekannten Sprach-Schwachstellen wird nach Defekten gesucht, gleichsam als eine Art frühzeitigem Test (auch bekannt als ‚shift left‘ – also Linksverschiebung auf der Zeitachse). Die Suche nach Defekten ist wichtig, doch sollte von Anfang an solide Software geschrieben werden. Gefragt sind daher Standards, durch die das Entstehen von Defekten von vornherein vermieden wird.
Die Industriestandards
Mäßige Qualität ist nur bis zum Ende der Codierphase billiger. Danach ist hohe Qualität billiger. [1; 2]
© ParasoftIndustriestandards für Safety und Security, wie MISRA C/C++, SEI/SANS CERT, OWASP Top 10 und CWE – Common Weakness Enumeration Top 25, verkörpern einen enormen Umfang an Arbeit. Obwohl ihr Einsatzgebiet je nach Typ eingeschränkt sein mag, finden sie Einsatz in vielen Branchen. Zum Beispiel MISRA C: Dieser im Jahr 1998 ins Leben gerufene Standard ist gut definiert und wird jeweils nach einigen Jahren aktualisiert. Mit der Weiterentwicklung der Sprachen C und C++ werden auch die dazugehörenden Standards weiterentwickelt. Der flexible Standard berücksichtigt verschiedene Schweregrade (severity levels) und es existiert eine dokumentierte Strategie zum Behandeln und Dokumentieren von Abweichungen. Da sich die Technologie zum Erkennen von Verletzungen der von Codierstandards aufgestellten Richtlinien weiterentwickelt, wird bei den neuesten MISRA-Versionen berücksichtigt, welche Richtlinien entscheidbar sind – also von Tools mit hoher Genauigkeit detektierbar – und welche nicht.
Die Rolle statischer Analysen
Studien belegen, dass unzureichende Fehlerbeseitigung die Hauptursache mangelhafter Softwarequalität ist. Programmierer erreichen beim Aufdecken von Defekten in ihrer eigenen Software eine Effizienz von etwa 35 %. Im späteren Verlauf des Entwicklungszyklus liegt die Zahl der Mängel, die nach allen Designprüfungen, Peer-Reviews, Unit-Tests und Funktionstests beseitigt werden, bei etwa 75 %. Die statische Analyse kann bei ordnungsgemäßem und präventivem Einsatz die Quote der eliminierten Defekte auf 85 % steigern. Allerdings legen die meisten Unternehmen den Fokus bei der statischen Analyse auf Auffinden und zügiges Beseitigen von Fehlern.
Dabei ergeben sich zusätzliche Vorteile, werden statische Analysetools von vornherein zur Vermeidung bekannter mangelhafter Programmierpraktiken und Sprach-Features benutzt. Hier kommen jene Codierstandards ins Spiel, die mittels Richtlinien und Sprach-Teilmengen unterbinden, dass Defekte wie Pufferüberläufe oder fehlende Initialisierungen überhaupt erst in den Code hineingeschrieben werden.
Arthur Hicken ist in den Bereichen Software-Security und Testautomatisierung bei Parasoft tätig.
© ParasoftAngenommen, in einem Test wird ein komplexer Pufferüberlauf-Fehler entdeckt, zum Beispiel mit einem Dynamic Application Security Tool (DAST). Nach Auffinden und Debuggen muss ein erneuter Test folgen. Die statische Analyse mit Flow-Analyse hätte diesen Fehler vielleicht auch gefunden, je nach Komplexität der Applikation. Die Laufzeit-Fehlerdetektierung ist zwar präzise, prüft aber nur die tatsächlich ausgeführten Codezeilen. Also kann sie nur so gut sein wie die Testabdeckung. Besser wäre es, wenn ein Codierstandard die Verwendung des Codes, der zu diesem Fehler führt, von vornherein unterbunden hätte.
Codierstandards wie MISRA C leiten die Programmierer an, ihren Code so zu schreiben, dass Fehler gar nicht erst vorkommen. Das ist eine deutlich ‚ingenieurmäßigere‘ Vorgehensweise: Programmieren nach bekannten und akzeptierten Standards. Wendet ein Softwareteam einen Codierstandard an und nutzt die statische Analyse richtig, kann es Fehler frühzeitig erkennen und vermeiden.
Besser ist es aber, die Art und Weise zu verändern, wie das Team den Code schreibt. Ein gutes Beispiel ist die Heartbleed-Schwachstelle. Es gibt inzwischen Detektoren für genau diese Sicherheitslücke, aber man hätte auch den Code so schreiben können, dass Heartbleed niemals aufgetreten wäre. Codierstandards verkörpern solide technische Prinzipien für das Programmieren in den jeweiligen Sprachen und bilden die Grundlage für ein vorbeugendes Konzept.
Literatur
[1] Jones, Caspers: Applied Software Measurement, 1996
[2] Morana, Marco M.: Building Security into The Software Life Cycle, 2006






![Mäßige Qualität ist nur bis zum Ende der Codierphase billiger. Danach ist hohe Qualität billiger. [1; 2] Mäßige Qualität ist nur bis zum Ende der Codierphase billiger. Danach ist hohe Qualität billiger. [1; 2]](https://www.industrial-production.de/imgproxy/w:480/h:270/el:1/rt:fill/g:sm/plain/https://www.industrial-production.de/upload_weka/nwo/004/076/1594901096_332_worf6iacz_4076995.jpg)









