Security MISRA C unterstützt beim Schreiben Security-bewusster Programme
Anbieter zum Thema
MISRA C bietet Entwicklern Richtlinien zur Erstellung sicherheitsbewusster Programme und hilft, die Anfälligkeit von C-Code zu reduzieren.

Die C-Sprache genießt bei Entwicklern nach wie wachsende Akzeptanz. Leider jedoch konnten Hacker bestehende Sicherheitslücken im Code stets schneller aufspüren und ausnutzen, als man den C-Standard mit entsprechenden Security-Updates nachbessern konnte. In der Tat birgt die C-Sprache Herausforderungen für security-kritische Anwendungen, denn in den zugrundeliegenden Standards (ISO/IEC 9899:2011 und 2018) fehlt es an umfassenden Spezifikationen dafür, wie sich Implementierungen zu verhalten haben. Zwar verleiht diese Unterlassung sowohl Entwicklern als auch unabhängig entwickelten Softwarepaketen mehr Flexibilität beim Management von Systemressourcen und Speicherzugriffen, jedoch kann diese Flexibilität zu einem unvorhersagbaren Verhalten führen. Unter dem Strich resultiert dies möglicherweise in Code, der – obwohl grundsätzlich korrekt geschrieben – eine Sicherheitslücke entstehen lässt.
Wenn Produkte, deren Finanz- und Zeitrahmen ohnehin schon knapp bemessen ist, von den Entwicklern mit noch mehr Features ausgestattet werden, erweist sich die Software als das schwache Glied der Kette, über das böswillige Akteure Zugriff auf sensible Daten erlangen und sogar ganze Systeme in ihre Hand bringen können. Für safety-kritische oder mit sensiblen Daten umgehende Systeme wird das Thema Security somit zu einem missionskritischen Aspekt.
Aber auch bei vielen nicht safety-kritischen Geräten ist die Bedeutung von Code, der auch im Sinne von „secure“ sicher ist, gewachsen. Selbst Geräte, die eigentlich niemals für eine Internetanbindung gedacht vorgesehen, werden im Zuge ihrer Weiterentwicklung oftmals mit einer Onlineverbindung ausgestattet, was bei kritischeren Systemen nicht selten unbefugten Zugriffen eine Hintertür öffnet. Überdies sind Sicherheitslücken unter Umständen schwierig zu finden, da sie möglicherweise nur unter bestimmten Bedingungen zu Fehlfunktionen führen. C-Entwickler benötigen deshalb zusätzliche Unterstützung beim Aufdecken und Eliminieren solcher Schwachstellen, und genau hier kommen die neuen MISRA C Guidelines ins Spiel.
Die Bedeutung von MISRA C für das Thema Security
MISRA C ist nach wie vor der führende Bestand an Richtlinien, die bei Embedded-Systemen vom Automotive- über den Avioniksektor bis hin zu Medizingeräten für das Schreiben von Code sorgt, der funktionssicher (safe), geschützt (secure) und zuverlässig ist.
Auch wenn oft das Gegenteil behauptet wird, war MISRA C niemals speziell auf den Safety-Aspekt ausgerichtet, sondern schon immer für die Verwendung bei security-kritischem Code geeignet. MISRA C definiert eine Teilmenge der C-Sprache, die die Fehlermöglichkeiten reduziert oder komplett eliminiert. Somit ist Code, der gemäß MISRA C geschrieben wurde, sehr wahrscheinlich von hoher Qualität, und qualitativ hochwertiger Code ist wiederum mit großer Wahrscheinlichkeit sowohl „safe“ als auch „secure“.
Um diese Position zu bekräftigen, umfassen die jüngst herausgegebenen MISRA-Updates sowohl das MISRA C:2012 Addendum 2, das MISRA C:2012 auf ISO/IEC 17961 „C Secure” abbildet, als auch MISRA C:2012 Addendum 3, das auf den Codierstandard CERT C abbildet und die neueren Editionen des C-Standards (C11 und C18) inkludiert.
Mit dem neuesten, im April 2023 veröffentlichten Release von MISRA C:2012 Amendment 4 (AMD4) erlangt MISRA eine höhere Relevanz als je zuvor. Dank des neuen Amendments fasst MISRA C:2023 sämtliche bisherigen Editionen und technischen Korrigenda von MISRA C in einem Dokument zusammen und zielt damit auf die enorme Herausforderung ab, die das Konfigurationsmanagement für Entwicklungs-Teams bisher darstellte.
Für C-Entwickler stellt die Verwendung automatisierter Verifikations-Tools, die die aktuellen MISRA-Richtlinien enthalten, eine bewährte Vorgehensweise zum Schreiben von Code dar, der durch ein Plus an Safety und Security gekennzeichnet ist. Es gibt zwar durchaus C-Compiler, die riskante Codierungen identifizieren können, aber der effizientere und kosteneffektivere Weg ist es, Probleme bereits im Vorfeld zu vermeiden, noch bevor sie den Weg in die Codebasis finden. Die Nutzung eines statischen Analysetools für die automatisierte Konformität zu MISRA C hilft, Probleme zum frühestmöglichen Zeitpunkt aufzudecken und zu beseitigen, und unterstützt Entwickler auf vielerlei Weise in ihrem Bemühen, sichereren Code hervorzubringen:
Reduzierung des Risikos gängiger Programmierfehler. Die MISRA C Guidelines enthalten Regeln zur Vermeidung häufig vorkommender Codierfehler, die zu Sicherheitslücken führen können. Es gibt beispielsweise Regeln, die eine explizite Typisierung verlangen, die Verwendung von Zeigerarithmetik einschränken oder Anforderungen für die Initialisierung von Variablen spezifizieren.
Verbesserung der Lesbarkeit und Pflegbarkeit des Codes. Die Richtlinien sind darauf ausgerichtet, die Lesbarkeit wie auch die Pflegbarkeit des Codes zu verbessern, sodass Sicherheitslücken einfacher gefunden und beseitigt werden können. Bei Einhaltung dieser Richtlinien schreiben Entwickler den Code außerdem so, dass sich die Prüfung und Pflege einfacher gestaltet, wodurch wiederum das Risiko sinkt, dass bei nachträglichen Codeänderungen Sicherheitslücken entstehen.
Förderung guter Codierpraktiken. Die Richtlinien fördern die Anwendung von Codierpraktiken, die das Risiko von Sicherheitslücken minimieren. Unter anderem verlangen die Richtlinien von den Entwicklern die Anwendung einheitlicher Codierstile, schränken die Verwendung globaler Variablen ein und nutzen keine nicht standardkonformen Sprachmerkmale.
Beispiele für Code mit unzureichender Security und Regeln zu ihrer Vermeidung
Viele Anforderungen, die sich auf die funktionale Sicherheit des Codes beziehen, gelten auch für die Security. Darüber hinaus bietet die Zusammenstellung expliziter Richtlinien zur Vermeidung bekannter Sicherheitslücken sowohl Entwicklern als auch statischen Analysetools einen Rahmen, mit dem sich die Security-Eigenschaften von Anwendungen verbessern lassen. MISRA C enthält 14 Richtlinien für security-bewusstes Programmieren in C, wodurch die in den ISO C Secure Guidelines hervorgehobenen Security-Bedenken abgedeckt werden. Mehrere dieser Richtlinien richten sich auf bestimmte Aspekte im Zusammenhang mit der Verwendung nicht vertrauenswürdiger Daten, die eine bekannte Security-Schwachstelle sind. Ein paar Beispiele aus den Richtlinien können bei der Demonstration einiger subtiler Aspekte helfen, die zu gravierenden Problemen führen können, wenn sie nicht richtig verstanden wurden.
Beispiel 1: Böswilligen Akteuren keine Türen öffnen
„Die Gültigkeit von Werten, die aus externen Quellen empfangen werden, ist zu überprüfen“ (Direktive 4.14)
Diese Direktive betrifft die Entgegennahme von Daten aus externen Quellen – ein Thema, das wegen der wachsenden Zahl von Geräten, die untereinander oder mit dem Internet verbunden sind, inzwischen große Bedeutung hat. Um möglichst wenig Angriffsflächen zu bieten, müssen solche Daten unbedingt validiert werden.
Der nebenstehende Codeabschnitt stellt eine potenzielle Sicherheitslücke dar, weil die Länge der von einer externen Quelle empfangenen Nachrichten nicht geprüft wird. Werden die Daten unter Überschreitung des zugewiesenen Speicherbereichs in voller Länge in einen Puffer kopiert, so stellt dies eine Sicherheitslücke dar, über die Angreifer das System korrumpieren oder sogar noch größere Schäden anrichten können.
Die Direktive impliziert die Notwendigkeit von „defensivem“ Code, um fortlaufend nicht nur zu prüfen, ob die empfangenen Daten in den erwarteten Rahmen passen (wie in dem Beispiel), sondern ob sie auch einen Sinn ergeben. Zum Beispiel lassen sich anhand einer Aufzeichnung der über die Zeit empfangenen Befehle unnormale Nutzungsmuster aufdecken, die beispielsweise auf eine Denial-of-Service-Attacke hindeuten können.
Beispiel 2: Verwendung der richtigen Funktion für die richtige Aufgabe
„Die Standard-Bibliotheksfunktion memcmp darf nicht zum Vergleichen null-terminierter Strings verwendet werden.“ (Regel 21.14)
Die memcmp()-Funktion ist dafür vorgesehen, die Inhalte von Speicherblöcken zu vergleichen. Sie darf dagegen nicht zum Vergleichen von Strings wie etwa Passwörtern benutzt werden, denn sie gibt mehr als einen True- oder False-Wert aus und eignet sich daher zum Aufdecken von Passwörtern in Datenbanksystemen. Sie gibt den Wert Null zurück, wenn beide Puffer den gleichen Inhalt haben, während bei unterschiedlichen Inhalten ein positiver oder negativer Wert zurückgegeben wird. Wird sie als Berechnung implementiert und der Wert auf der einen Seite kontrolliert, kann die Funktion so oft aufgerufen werden, bis der Wert auf der anderen Seite, bei dem es sich beispielsweise um ein Passwort handeln kann, ermittelt ist. Tatsächlich ist in der Manpage zu memcmp() explizit zu lesen, dass diese Funktion nicht zum Vergleichen sicherheitskritischer Daten verwendet werden darf.
Im Codebeispiel (links) wird memcmp() zum Vergleichen von Strings verwendet, obwohl eigentlich strcmp() benutzt werden sollte.
Beispiel 3: Wenn jemand Ihre Art zu sprechen kontrolliert, kann er Sie dazu bringen, alles zu sagen, was er will
„Der von den Standard-Bibliotheksfunktionen asctime, ctime, gmtime, localtime, localeconv, getenv, setlocale oder strerror zurückgegebene Zeiger darf nicht für einen anschließenden Aufruf derselben Funktion benutzt werden.“ (Regel 21.10)
Lokale Nachrichten kontrollieren die Formatierung von Strings und definieren damit effektiv die Art und Weise, wie die Software „spricht“. Sobald Hacker also Einfluss auf die Formatierung von Strings erlangen, können sie die von ihnen gewünschten Aussagen erzwingen und beispielsweise kontrollieren, mit welchen anderen Programmen das erste Programm interagiert. Diese Strings lassen sich folglich dazu verwenden, beliebige Befehle auszuführen und ein System in die Hand zu bekommen.
Das nebenstehende Codebeispiel funktioniert möglicherweise nicht wie vorgesehen, da der zweite Aufruf von setlocale() zu dem von „res1“ referenzierten String führen kann, der aber der gleiche ist wie der von „res2“ referenzierte. Von der Korrektheit abgesehen, wurde das Kontrollieren von locale in Exploits genutzt, in denen Strings umformatiert wurden, um die Verarbeitung von Befehlen auf einem entfernten Computer zu erleichtern.
Vereinfachte Konformität zu MISRA C
Infolge der Komplexität und des Umfangs heutiger Software ist es unrealistisch, die Prüfung auf Konformität zu MISRA C auf manuellem Weg vorzunehmen. Um Code auf die Einhaltung von Standards und Richtlinien zu prüfen, wird stattdessen in erster Linie auf automatische statische Analysetools gesetzt. Um Verletzungen dieser Richtlinien zu finden und zu korrigieren, bedarf es statischer Analysetools, in die diese Richtlinien gleichsam eingebaut sind und die potenzielle Sicherheitsmängel in einem ganz frühen Stadium aufdecken können, damit sie von den Entwicklern noch vor der Kompilierung des Codes korrigiert werden können. (mbf)
* Mark Pitchford arbeitet mit Entwicklungsteams zusammen, die eine konforme Softwareentwicklung in sicherheitskritischen Umgebungen anstreben, mit Standards wie DO-178, IEC 61508, ISO 26262, IIRA und RAMI 4.0. Er ist ein technischer Spezialist bei LDRA Software Technology.
(ID:49587019)