Seien Sie am 30. April dabei: Vorstellung von Parasoft C/C++test CT für kontinuierliche Tests und Compliance-Exzellenz | Registrierung

Eine Unze Prävention: Sicherheit durch Software-Codierungsstandards

Kopfschuss von Arthur Hicken, Evangelist bei Parasoft
4. August 2023
8 min lesen

Die Implementierung und Aufrechterhaltung des richtigen Codierungsstandards für Ihre Entwicklungsprojekte ist der Schlüssel zur Bereitstellung sicherer Softwarelösungen. In diesem Beitrag erläutert unser Experte, warum Sie sicherstellen sollten, dass Sie den richtigen Codierungsstandard einhalten und wie Sie dies tun können.

Die Software wurde vom Desktop auf nahezu alles verlagert, was wir berühren. Von intelligenten Thermostaten über Infusionspumpen bis hin zu Autos ist die Software allgegenwärtig und wächst. Die sogenannten „Dinge“ aus dem Internet der Dinge (IoT) tragen zunehmend mehr Logik in sich. Damit verbunden ist ein größeres Risiko des Scheiterns. Viele dieser Geräte werden in sicherheitskritischen Bereichen wie der Medizin und im Automobilbereich eingesetzt, wo die Gefahr von Körperverletzungen besteht.

Die meisten Unternehmen, die Geräte bauen, betrachten die aktuelle Softwareentwicklung zu Recht als eine fast verrückte Gruppe von Cowboys und Chaos. Aber es gibt Hoffnung. Software kann und muss als technische Praxis behandelt werden. Codierungsstandards, die Teil einer guten Softwareentwicklungspraxis sind, führen uns vom Zyklus „Erstellen, Versagen, Reparieren“ zu einem Zyklus „Entwerfen, Erstellen, Liefern“ mit hoher Qualität, Sicherheit und Schutz.

Wie sich herausstellt, bieten dieselben Standards auch Vorteile in den Bereichen Cybersicherheit, da sie doppelte Pflichten erfüllen. Dieser Beitrag beschreibt:

  • Wie diese Standards uns helfen, von der Suche nach Fehlern zur Entwicklung robusterer Software überzugehen.
  • So verhindern Sie Probleme mit der richtigen Codierung.
  • Wie Sie die Bemühungen anderer nutzen können, indem Sie allgemein anerkannte Industriestandards wie MISRA verwenden, um dieses Ziel zu erreichen.

Softwareentwicklung zum Software Engineering

Die Auswirkungen von Software auf die reale Welt werden häufig nicht berücksichtigt. Eines meiner Hauptthemen, über das ich als Evangelist bei Parasoft ständig diskutiere, ist, dass Softwareentwicklung eigentlich Engineering sein sollte.

Wir nennen Softwareentwickler häufig Softwareentwickler, aber das ist nicht unbedingt die richtige Bezeichnung für ihre heutige Arbeitsweise. Die Weiterentwicklung zu einer guten Software-Engineering-Praxis führt dazu, dass die Kosten sinken und die Qualität steigt. Ein wesentlicher Teil davon ist die Übernahme von Standards – insbesondere von Codierungsstandards.

Das Zeitalter softwaredefinierter Fahrzeuge, medizinischer und industrieller IoT-Geräte sowie ständig vernetzter Geräte ist angebrochen. Software schleicht sich in Produkte, Geräte und andere Orte ein, an die wir nie gedacht hätten. Wir müssen jetzt gründlich über die Software in diesen Produkten und die damit verbundenen Auswirkungen nachdenken.

Die Kosten für schlechte Qualität

Eines der interessanten Dinge, die ich zu erklären versuche, ist, dass das Erstellen guter Software sich vom Erstellen eines Autos unterscheidet. Wenn ich versuche, ein hochwertiges Auto zu bauen, muss ich mehr für Materialien und mehr Zeit für den Bau aufwenden. Es stellt sich heraus, dass Sie in Software nicht mehr für die Erstellung hochwertiger Software ausgeben. Sie geben mehr aus, um Software von schlechter Qualität zu erstellen.

Wir müssen verstehen, dass in der Software die meisten Fehler vom Programmierer stammen, der sie in das Produkt einfügt. Wenn wir bei der Entwicklung der Software keine Fehler mehr einführen können, können wir viel bessere Software zu einem niedrigeren Preis haben.

Dieses Zitat stammt aus einem Gespräch aus dem Jahr 1972 mit dem Titel „Der bescheidene Programmierer“, geschrieben von Edsger W. Dijkstra. Es ist auch heute noch sehr aktuell.

Zitat aus „The Humble Programmer“, geschrieben von Edsger W. Dijkstra

Es ist wichtig zu wissen, wie sich Qualität auf die Kosten der Softwareentwicklung auswirkt. Kapern JonesDer Forscher verfolgt dies seit Jahrzehnten und führt jedes Jahr eine Umfrage zu den Softwarekosten durch. Die Zahlen ändern sich nicht viel von Jahr zu Jahr. Die Daten zeigen, dass die typischen Softwarekosten von den Anforderungen über die Codierung bis zur Wartung mit jeder Phase steigen. Die Art und Weise, wie Teams sich der Qualität nähern, bestimmt jedoch, ob ihr Prozess gesund oder „pathologisch“ ist.

Diagramm, das Kosten im Verhältnis zur Zeit zeigt und zeigt, wie Code von schlechter Qualität bis zum Ende der Codierungsphase billiger ist, danach ist Code von hoher Qualität billiger.
Softwarequalität 2011: Ein Überblick über den Stand der Technik in der Software – Capers Jones

Warum wir Fehler frühzeitig beheben müssen

Es macht Sinn, dass die Kosten relativ gering sind, wenn wir einen Fehler direkt beim Schreiben des Codes finden – zum Beispiel ein paar Minuten Zeit eines Entwicklers. Wenn es gelingt, 85 % der Fehler in der Entwicklungsphase zu beseitigen, hat das große Auswirkungen auf die Kosten. Betrachten Sie die mittlerweile berühmte Grafik von Capers Jones, die die durchschnittlichen Kosten für die Behebung von Fehlern in jeder Entwicklungsphase zeigt:

Diagramm, das den Prozentsatz der bei der frühen Codeprüfung in Pentest/späte Codeprüfung eingeführten Fehler und die erhöhten Kosten für die spätere Reparatur von Fehlern zeigt.
Quellen – Applied Software Measurement, Capers Jones, 1996, Building Security into The Software Life Cycle, Marco M. Morana, 2006

Die Behebung von Fehlern nach der Veröffentlichung kostet etwa 16,000 US-Dollar (möglicherweise viel mehr), basierend auf Untersuchungen zu realen Unternehmen, die echte Software entwickeln, und nicht auf einem theoretischen Modell. Wenn wir uns die späten Qualitäts- und Sicherheitsbemühungen wie Penetrationstests ansehen, stellen wir fest, dass die hier festgestellten Sicherheitsprobleme am teuren Ende des Zyklus liegen. Es ist wahrscheinlich 15-mal so teuer wie das Auffinden von Schwachstellen durch Tests im Vergleich zu frühen Sicherheitsüberprüfungen.

Ein veralteter und nachweislich falscher Ansatz besteht darin, die Qualität Ihrer Software zu verbessern, indem Sie sie am Ende des Lebenszyklus, kurz vor der Veröffentlichung, testen. In der Fertigungswelt ist ihnen klar, dass dies unmöglich ist, aber aus irgendeinem Grund glauben wir, dass wir Qualität und Sicherheit „in“ Software testen können.

Die Gründe, warum ich sage, dass Softwareentwicklung fast nie Engineering ist, sind diese gemeinsamen Merkmale der aktuellen Softwareentwicklung:

  • Was die meisten Entwickler tun, ist nicht wiederholbar. Das heißt, wenn ich zwei verschiedenen Personen dieselbe Aufgabe gebe, sind die Ergebnisse nicht dieselben.
  • Mangel an gut ausgeübten Best Practices. Softwareentwickler betrachten Codierungsstandards als ein Wort, das wenig Bedeutung hat. Unter Standards versteht man eine Reihe von Regeln, die der Teamleiter unbedingt befolgen muss, anstatt zu verstehen, dass der Codierungsstandard die Verkörperung von Wissen, Praxis und Erfahrung ist. Ein Elektroingenieur weiß, dass Standards der Weg sind, um gleich beim ersten Mal ein sicheres Produkt zu bauen. Ein Softwareentwickler denkt, dass Standards eine Einschränkung darstellen, die ihn verlangsamt … ein „Fehlalarm"
  • Entwicklerschulungen sind unbekannt und inkonsistent. Die Ausbildung in Softwareentwicklung ist nicht wie in technischen Disziplinen standardisiert. Standards und etablierte Praktiken sind oft nicht Teil des Lehrplans, sondern der Schwerpunkt liegt auf Programmiersprachen.

Codierungsstandards verbessern die Sicherheit

Das Ziel von Software-Codierungsstandards besteht darin, bewährte Programmierpraktiken einzuführen, die zu sicherem, zuverlässigem, testbarem und wartbarem Code führen. In der Regel bedeutet dies, bekannte unsichere Codierungspraktiken oder Code zu vermeiden, der unvorhersehbares Verhalten verursachen kann. Dies wird in Programmiersprachen wie C und C++ von entscheidender Bedeutung, in denen das Potenzial hoch ist, unsicheren oder unsicheren Code zu schreiben.

Ich denke jedoch, dass sich die Branche mit diesen Programmierstandards verirrt hat. In den letzten zehn Jahren haben sich die Tools (z. B. statische Analysetools) von der Erkennung potenziell problematischer Codes, die unsicher sind oder eine bekannte Sprachschwäche aufweisen, zu einem Fokus auf die Suche nach Fehlern als eine Form des frühen Testens, auch als Linksverschiebung bezeichnet, verschoben.

Obwohl das Suchen nach Fehlern wichtig ist, ist das Erstellen von Sound-Software eine produktivere Aktivität. Was wir tun sollten, ist die Erstellung und Durchsetzung von Standards, um die Situation zu vermeiden, in der Fehler überhaupt erst auftreten - und noch weiter nach links zu verschieben.

Um dies zu sichern, betrachten Sie die Forschungsprojekte Dies wurde vom Software Engineering Institute (SEI) durchgeführt, wo nicht überraschend festgestellt wurde, dass Sicherheit und Zuverlässigkeit Hand in Hand gehen und dass die Sicherheit von Software anhand der Anzahl und Art der festgestellten Qualitätsfehler vorhergesagt werden kann. Darüber hinaus sind kritische Fehler häufig Codierungsfehler, die durch Inspektionen und Tools wie statische Analysen verhindert werden können.

Industriestandards

Dieser Beitrag geht nicht näher auf jeden dieser Codierungsstandards ein, es gibt jedoch eine beträchtliche Menge an Arbeit in den folgenden Industriestandards. Obwohl ihre Anwendung möglicherweise spezifisch für einen bestimmten Typ ist, werden diese Standards in vielen Branchen übernommen. Hier sind einige Beispiele etablierter Codierungsstandards für Sicherheit und Schutz.

  • MISRA C/C++. Es wurde von der Motor Industry Software Reliability Association entwickelt und beschreibt eine Teilmenge der C- oder C++-Sprache sowie Richtlinien für deren Verwendung, um die Sicherheit der Anwendung zu verbessern. Obwohl es ursprünglich für Automobilanwendungen gedacht war, wird es in allen Branchen eingesetzt, insbesondere für sicherheitskritische Anwendungen. „MISRA“, „MISRA C“ und das Dreieckslogo sind eingetragene Marken von The MISRA Consortium Limited. ©The MISRA Consortium Limited, 2021. Alle Rechte vorbehalten.
  • SEI / SANS CERT. Das Computer Emergency Response Team (CERT) des Software Engineering Institute (SEI) verfügt über eine Reihe von Richtlinien, die Entwicklern helfen sollen, sicherere, sicherere und zuverlässigere Software zu erstellen. Die Richtlinien werden durch Gruppen von „Regeln“ und „Empfehlungen“ in ihre Bedeutung unterteilt. Sie sind sehr gründlich und umfassend und enthalten Risikometadaten.
  • OWASP Top 10. Das Open Web Application Security Project (OWASP) ist, wie der Name schon sagt, eine Organisation, die sich der Verbesserung der Sicherheit von Webanwendungen verschrieben hat. Daher bietet ihr OWASP Top 10-Projekt eine Liste der häufigsten und schwerwiegendsten Sicherheitslücken in Webanwendungen. Die neueste Version von OWASP Top 10 ist direkt mit spezifischen CWE-IDs korreliert und enthält Risikometadaten.
  • Joint Strike Fighter Luftfahrzeug C ++ Codierungsstandard (JSF AV). Ein Standard, der auf einer Teilmenge von MISRA C speziell für das JSF-Programm basiert.
  • CWE - Common Weakness Enumeration Top 25. CWE ist eine Liste der entdeckten Software-Schwachstellen, die auf der Analyse der gemeldeten Schwachstellen (CVEs) basiert. In den Top 25 sind die häufigsten und gefährlichsten Sicherheitslücken aufgeführt, die aus der größeren Liste der CWEs ausgewählt wurden. Hierbei handelt es sich um Exploits, bei denen eine hohe Wahrscheinlichkeit des Auftretens besteht und die Auswirkungen der Ausnutzung der Schwachstelle groß sind. CWE enthält auch Risikoinformationen in Form von technischen Auswirkungen, um zu verstehen, welche Probleme für Ihr Unternehmen am wichtigsten sind.

Lassen Sie uns überlegen MISRA C., das ich erwähnt habe, ist nicht nur für Automobilanwendungen gedacht. Es handelt sich jedoch um einen Standard, der seit 1998 verwendet wird und klar definiert ist. Es wird alle paar Jahre aktualisiert. Während sich die Sprachen C und C++ weiterentwickeln, entwickeln sie auch die Standards dafür weiter. Es handelt sich um einen sehr flexiblen Standard, der unterschiedliche Schweregrade berücksichtigt und über eine dokumentierte Strategie für den Umgang und die Dokumentation von Abweichungen verfügt.

Da es sich um eine Technologie handelt, die Verstöße gegen Codierungsstandardrichtlinien, wie z. B. die statische Analyse, erkennen kann, berücksichtigen neuere Versionen von MISRA, welche Richtlinien entscheidbar (mit hoher Präzision durch Tools erkennbar) sind und welche nicht. Dies bringt uns zum Thema der Einführung und Durchsetzung und der Bedeutung statischer Analysetools in Codierungsstandards.

Rolle der statischen Analyse

Untersuchungen zeigen, dass eine unzureichende Fehlerbeseitigung die Hauptursache für qualitativ schlechte Software ist. Programmierer sind zu etwa 35 % effizient darin, Fehler in ihrer eigenen Software zu finden. Später im Entwicklungszyklus liegen die meisten Fehler, die wir nach all den Design-Reviews, Peer-Reviews, Unit-Tests und Funktionstests beseitigen können, bei etwa 75 %.

Eine statische Analyse kann bei ordnungsgemäßer Verwendung in einem vorbeugenden Modus die Fehlerbeseitigung auf etwa 85% erhöhen. Der Schwerpunkt der statischen Analyse für die meisten Unternehmen liegt heute jedoch auf der Erkennung und der schnellen Lösung.

Weitere Vorteile sind möglich, wenn statische Analysewerkzeuge verwendet werden, um bekannte schlechte Programmierpraktiken und Sprachfunktionen zu verhindern. Hier kommen Codierungsstandards als Richtlinien und Teilmengen der Programmiersprache ins Spiel, die verhindern, dass häufig auftretende Fehler wie Pufferüberläufe oder fehlende Initialisierung in den Code geschrieben werden.

Eine Unze Prävention

Stellen Sie sich ein Beispiel vor, bei dem beim Testen ein ziemlich komplexer Pufferüberlauffehler erkannt wird, möglicherweise mit einem dynamischen Anwendungssicherheitstool (DAST). Dies ist ein Glücksfall, da Ihr Test gerade den Codepfad ausgeführt hat, der den Fehler enthält. Sobald es erkannt und debuggt wurde, muss es erneut getestet werden und so weiter. Bei einer statischen Analyse mithilfe der Flussanalyse wurde dieser Fehler möglicherweise ebenfalls gefunden, dies hängt jedoch von der Komplexität der Anwendung ab.

Die Erkennung von Laufzeitfehlern ist präzise, ​​überprüft jedoch nur die von Ihnen ausgeführten Codezeilen. Es ist also nur so gut wie Ihre Testcode-Abdeckung. Überlegen Sie, ob ein Codierungsstandard den Code verboten hat, der diesen Fehler überhaupt aktiviert hat.

Codierungsstandards wie MISRA C beschreiben beispielsweise nicht, wie nicht initialisierter Speicher erkannt wird, sondern leiten Programmierer vielmehr dazu an, Code zu schreiben, der gar nicht erst zu einem solchen Fehler führt. Ich glaube, das ist eher ein technischer Ansatz: Programmieren nach bekannten und anerkannten Standards. Nehmen wir zum Beispiel Tiefbau und Brückenbau.

Wir würden nicht den Ansatz verfolgen, eine Brücke zu bauen und sie dann zu testen, indem wir immer größere Lastwagen darüber fahren, bis sie einstürzt, das Gewicht des letzten erfolgreichen Lastwagens messen und sie dann erneut bauen, um diesem neuen Gewicht standzuhalten. Dieser Ansatz wäre jedoch dumm, er ähnelt jedoch nicht unähnlich der Art und Weise, wie wir an die Softwareentwicklung herangehen.

Sobald ein Softwareteam einen Codierungsstandard anwendet und die statische Analyse ordnungsgemäß angewendet wird, kann es Fehler frühzeitig erkennen und verhindern. Mit anderen Worten, anstatt frühzeitig einen Fehler zu finden, was gut ist, ändert das Team die Art und Weise, wie Code geschrieben wird, was besser ist!

Betrachten Sie die Heartbleed Verletzlichkeit. Es gibt jetzt Detektoren für diese spezielle Sicherheitsanfälligkeit, aber es gibt eine Möglichkeit, Code so zu schreiben, dass Heartbleed überhaupt nicht hätte passieren können. Prävention ist eine bessere und sicherere Methode.

Zusammenfassung

Dykstra sagte: "Diejenigen, die wirklich zuverlässige Software wollen, werden feststellen, dass sie Mittel finden müssen, um die meisten Fehler zu vermeiden." Eine solide Präventionsmethode ist weniger als die Kosten für die Behebung dieser Fehler.

Codierungsstandards verkörpern fundierte technische Prinzipien für die Programmierung in ihren jeweiligen Sprachen und bilden die Grundlage für jeden präventiven Ansatz. Die Kosten für gute Software sind geringer als die Kosten für schlechte Software. Wenn Sie heute keine statische Analyse verwenden oder sie nur zur Früherkennung verwenden, werfen Sie einen Blick auf die statischen Analysetools von Parasoft für C und C ++, Javac und C # und VB.NET mit einer umfangreichen Bibliothek von Checkern für alle gängigen Sicherheitsstandards.

Auswählen und Implementieren des richtigen sicheren Codierungsstandards