10 Standards für sichere Software

SEI CERT Coding Standards der Carnegie Mellon University

| Autor / Redakteur: Mirco Lang / Stephan Augsten

Security by Design beginnt per Definition schon vor der Code-Erstellung, sollte aber beim Programmieren konsequent umgesetzt werden.
Security by Design beginnt per Definition schon vor der Code-Erstellung, sollte aber beim Programmieren konsequent umgesetzt werden. (Bild: TheDigitalArtist - Pixabay.com / CC0)

Security by Design sollte schon vor der ersten Zeile Code ansetzen, aber natürlich gilt Gedanke auch für den Quelltext selbst. Von der Carnegie Mellon University gibt es hierzu umfangreiche Materialien.

Die Carnegie Mellon University hat in der Welt der IT-Sicherheit einen sehr guten Ruf, schließlich entstammt dessen Software Engineering Institute (SEI) das erste CERT (Computer Emergency Response Team). Auf den CERT-Secure-Coding-Seiten finden Sie allerlei Dokumente rund um sicheren Code.

Den Grundstein legen die übersichtlichen „Top 10 Secure Coding Practices“, die allgemeine Grundsätze für die Entwicklung aufzeigen. Jeder Programmierer sollte sie zumindest einmal gesehen haben. Der eigentliche Content der Seite ist allerdings deutlich umfangreicher: Konkrete Coding-Standards für sichere, zuverlässige Anwendungen in diversen Programmiersprachen. Doch zunächst die Top 10 in der Übersicht.

Top 10 Secure Coding Practices

Wer die OWASP Top 10 zu den Security-by-Design-Prinzipien noch nicht kennt, sollte darauf zumindest einmal einen Blick werfen: Diese liefern zwar keine konkreten Tipps für das Erstellen von Code, dennoch gibt es einige Parallelen – beispielsweise die Anregung, die Architektur – beziehungsweise hier den Code – möglichst einfach zu halten.

Im Grunde ergänzen sich beide Top 10 sehr gut. Die OWASP spricht Entwickler im Allgemeinen und auch das IT-Management an, das SEI richtet sich zwar mit den einzelnen Sprach-Standards konkret an Coder, mit der Top 10 aber genauso an Architekten und Designer.

Input validieren

Jeglicher Input nicht vertrauenswürdiger Quellen sollte validiert werden. Dazu zählen nicht bloß von Nutzern übergebene Daten und Dateien, sondern auch Input von Netzwerkschnittstellen, Umgebungsvariablen, Argumente aus CLI-Aufrufen und so weiter. Nicht geprüfte Datenflüsse zählen zu den häufigsten Ursachen für Anfälligkeiten.

Compiler-Warnungen beachten

Kompilieren Sie immer mit dem höchsten Detaillevel für Warnmeldungen und beseitigen Sie Stück für Stück. Detaillierte Informationen, wie Sie das beispielsweise mit C-Code erledigen, finden Sie ebenfalls auf den CERT-Secure-Coding-Seiten.

Architektur für Sicherheitsrichtlinien

Die Empfehlung geht komplett d'accord mit der OWASP-Top-10: Sie sollten schon bei Design und Architektur der Anwendung so planen, dass Sicherheitsrichtlinien implementiert und deren Umsetzung erzwungen werden kann. Als Beispiel führt das SEI hier unterschiedliche Privilegien der Anwendungen zu unterschiedlichen Zeitpunkten an. So ist es eine Überlegung wert, die Applikation so zu gestalten, dass sie aus mehreren Subsystemen mit jeweils passgenauen Rechten besteht, die dann untereinander kommunizieren. Allerdings sollten Sie nicht mit der folgenden Regel streiten:

Keep it simple

Es einfach zu halten ist ein Tipp, den man im Grunde überall und ständig bekommt – auch in der OWASP-Top-10 zum Beispiel. Ein arg komplexes Softwaredesign ist schwierig zu warten, zu patchen und überhaupt zu verifizieren. Zudem erhöht es massiv das Risiko, dass bei Implementierung, Konfiguration oder Nutzung etwas schief geht. Und das gilt nicht nur für das grundsätzliche Design, sondern auch für die Code-mäßige Umsetzung einzelner Funktionen.

Standardmäßig kein Zugriff

Zugriff auf jegliche Ressourcen sollte standardmäßig verboten sein und nur bei entsprechenden Bedingungen gewährt werden. Mit anderen Worten: Zugriff sollte über White- nicht über Blacklisting erfolgen.

Prinzip der minimalen Rechte

Ganz ähnlich sieht es mit der Höhe der Privilegien aus, die Prozesse innehaben: Erhöhte Rechte sollten nur dann und nur so lange gewährt werden, wie sie auch benötigt werden. Bei Warnmeldungen zu Softwarelücken liest man immer wieder das Textfragment „An attacker could execute arbitrary with elevated privileges.“

Soll heißen: Eine Anwendung (oder ein Teil davon) läuft beispielsweise mit Adminrechten, weil Systemeinstellungen vorgenommen werden müssen. Werden diese Rechte nicht umgehend wieder aufgegeben und findet ein Angreifer eine Möglichkeit, Daten zu übergeben, könnte er darüber eben solchen beliebigen Code mit den erhöhten Rechten ausführen – und schon ist die Katastrophe nah!

Versendete Daten säubern

Dieser Tipp ist im Grunde komplementär zum vorigen: Daten, die an komplexe Subsysteme gesendet werden, sollten gesäubert werden – quasi die Gegenseite vom ersten Prinzip. Das bekannteste Stichwort hier: SQL Injection. Wenn Daten an eine Drittanbieterbibliothek, eine Kommandozeile oder eben eine SQL-Datenbank übergeben werden, sollten es auch nur die gewünschten, geduldeten Daten in dieses Subsystem schaffen.

Eine SQL-Datenbank kann zum Beispiel Dinge wie neue Nutzer anlegen und verschlüsselte Passwörter ausgeben. Wenn Nutzer nun aber lediglich normale Abfragen absetzen können sollen, muss der Abfrage-Code, den diese übergeben entsprechend geprüft und bereinigt werden, damit unerwünschte Befehle gar nicht erst bei der Datenbank ankommen. Natürlich kann man dafür auch rollenbasierte Einschränkungen auf Datenbankseite nutzen, was auch gleich zum nächsten Punkt führt.

Verteidigung in der Tiefe

Wieder mal ein Punkt, der genauso bei den OWASP-Best-Practices auftaucht: Betreiben Sie Ihr Risikomanagement über mehrere Abwehrstrategien parallel. Das könnte zum einen bedeuten, dass ein Angreifer mehrere Hürden nehmen muss, bevor er überhaupt aktiv werden kann. Oder aber, dass der Schaden, den er nach der ersten überwundenen Hürde anrichten kann abgemildert wird. Natürlich sollten Sie hier jedoch nicht unendlich verschachteln – der Keep-it-simple-Grundsatz sollte niemals zu sehr leiden.

Qualitätssicherung

QS erfreut sich vielerorts nicht unbedingt großer Beliebtheit, korrekt umgesetzt ist sie aber ein wichtiger Baustein für sicheren Code: Umfangreiche Testverfahren, externe Code Audits und festgezurrte Prozesse für deren Einsatz sind die besten Garanten, um Code möglichst fehlerfrei und unanfällig zu bekommen.

Coding-Standard etablieren

Zu guter Letzt kommt die Empfehlung einen konkreten Coding-Standard zu entwickeln oder zu adaptieren. Eine eigene Entwicklung dürfte nur für die ganz Großen der Branche in Frage kommen, ansonsten seien Ihnen die Dokumente auf den CERT-Secure-Coding-Seiten ans Herz gelegt.

Secure Coding Standards

Auf der SEI-CERT-Homepage finden sich umfangreiche Werke zu Android, C, C++, Java und Perl. Für C und C++ stehen auch komplette eBooks als PDFs zur Verfügung, die C++-Variante beispielsweise mit 435 Seiten. Die PDFs verstehen sich als offizielle Releases, die Webseiten selbst werden als Wiki betrieben. Und wie es für Wikis generell und das Thema Programmierung ganz speziell gilt: Hier können auch Fehler vorkommen, zumal das Ganze als Work in Progress bezeichnet und natürlich von einer Community betrieben wird. Allerdings ist die Bearbeitung nur für registrierte Nutzer möglich.

Der C++-Standard als PDF beschreibt jeweils ein Problem, gibt Informationen zu den Risiken und zeigt Beispiele für konformen und nicht konformen Code. Im Wiki finden sich zusätzliche Informationen wie zum Beispiel die zugehörigen Schwachstellen in Form von CVEs und Möglichkeiten zur automatischen Detektion der beschriebenen Probleme.

Damit Sie einen Eindruck vom eigentlichen Inhalt bekommen, hier mal ein konkret adressiertes Problem, wie es im PDF zu finden ist: Unter Punkt „4 Integers (INT)“ wird auf dreieinhalb Seiten der Umgang mit falschen Werten abgehandelt, der zu Buffer Overflows führen könnte; konkret: „Do not cast to an out-of-range enumeration value“. Nach einer nicht konformen Variante werden konforme Code-Beispiele für drei unterschiedliche Ausprägungen des Problems (Bounds Checking, Scoped und Unscoped Enumeration) kurz und bündig mit Code und ein paar wenigen Zeilen Erklärung ausgeführt. Den Abschluss bildet die Risikoeinschätzung, die hier ein mittleres Risiko und eher unwahrscheinliches Auftreten bestätigt.

Der Aufbau des Coding-Standards ist immer gleich und mit konkreten Code-Beispielen versehen.
Der Aufbau des Coding-Standards ist immer gleich und mit konkreten Code-Beispielen versehen. (Bild: Carnegie Mellon University SEI)

Die Standards richtien sich ganz offensichtlich an Programmierer, werden aber auch dem IT-Management empfohlen, wenn es beispielsweise darum geht konkrete Coding-Richtlinien für einzelne Projekte zu entwickeln. Für das Verständnis bedarf es jedoch eindeutig tiefergehender Sprachfertigkeiten.

Kommentare werden geladen....

Kommentar zu diesem Artikel

Der Kommentar wird durch einen Redakteur geprüft und in Kürze freigeschaltet.

Anonym mitdiskutieren oder einloggen Anmelden

Avatar
Zur Wahrung unserer Interessen speichern wir zusätzlich zu den o.g. Informationen die IP-Adresse. Dies dient ausschließlich dem Zweck, dass Sie als Urheber des Kommentars identifiziert werden können. Rechtliche Grundlage ist die Wahrung berechtigter Interessen gem. Art 6 Abs 1 lit. f) DSGVO.
  1. Avatar
    Avatar
    Bearbeitet von am
    Bearbeitet von am
    1. Avatar
      Avatar
      Bearbeitet von am
      Bearbeitet von am

Kommentare werden geladen....

Kommentar melden

Melden Sie diesen Kommentar, wenn dieser nicht den Richtlinien entspricht.

Kommentar Freigeben

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

Freigabe entfernen

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Kontaktieren Sie uns über: support.vogel.de/ (ID: 45685701 / Application Security)