Lösbarer Konflikt – Safety und Security in der Softwareentwicklung

Autor / Redakteur: Richard Bellairs * / Sebastian Gerstl |

Sicherheit ist mehr als nur ein Wort: Safety und Security bei der Softwareentwicklung unter einen Hut zu bringen kann aufgrund unterschiedlicher Regelsätze eine Herausforderung darstellen. Aber sie kann gemeistert werden.

Anbieter zum Thema

Da Safety und Security zum Teil unterschiedliche Regelsätze und Protokolle verwenden, zogen es Softwareentwickler in der Vergangenheit vor, eines der beiden über das andere zu priorisieren – meist zu Lasten der Security. Doch das ist nicht zwingend nötig.
Da Safety und Security zum Teil unterschiedliche Regelsätze und Protokolle verwenden, zogen es Softwareentwickler in der Vergangenheit vor, eines der beiden über das andere zu priorisieren – meist zu Lasten der Security. Doch das ist nicht zwingend nötig.
(Bild: gemeinfrei / CC0 )

Mit jeder neuen Entwicklung in der IT rückt die Welt ein Stück näher zusammen. Und je enger die Verknüpfung wird, desto anfälliger wird sie für Angriffe von außen. Das zeigt auch die jüngste Vergangenheit: Industrieunternehmen wurden durch Angriffe auf ihre IT-Infrastruktur in die Knie gezwungen und bisweilen sogar in ihren Grundfesten erschüttert. Unternehmen, die sich sicher – zu sicher – fühlten, wurden eines Besseren belehrt.

Das Englische (wie auch die Informatik) kennt zwei Begriffe für Sicherheit: Safety und Security. Im Deutschen wird die begriffliche Unterscheidung so nicht getroffen. Aus diesem Grund bleibe ich dort, wo es notwendig ist, bei den englischen Bezeichnungen. Lange Zeit lag der Schwerpunkt der Entwicklungsarbeit in Bezug auf Sicherheit bei der Safety der Anwendung. Die Security stand weniger im Fokus, obwohl beide – Safety und Security – unterschiedliche Regelsätze und Protokolle verwenden. Doch manches haben sie auch gemeinsam. Und genau unter diesem Aspekt ist es möglich, beim Erstellen von Code beides in einem ganzheitlichen Ansatz „unter einen Hut“ zu bringen.

Und das ist auch wichtig. Denn die Frage nach Safety und Security stellt sich in jeder Anwendung, besonders aber im sicherheitskritischen Bereich. So ist es mitunter schwer, eine formale Definition dessen zu finden, was sicher (safe) und sicher (secure) bedeuten soll, wenn es um Softwareentwicklung geht.

Es gibt zwar funktionale Sicherheitsstandards wie IEC61508 oder ISO26262. Aber wenn man anerkannte Coding-Standards der Industrie für hochintegrierte Systeme mit denen für sicherheitskritische Software vergleicht, wird einem schnell klar: es gibt viele Gemeinsamkeiten. Und vor allem eine große, gemeinsame Grundlage.

Wer setzt die Grenzen, wenn es um Safety- und Security-Features einer Programmiersprache wie C oder C++ geht? Es ist die Sprache selbst. Aus ihr gehen Styles und Vorgehensweisen hervor, die darauf abzielen, Safety und Security einer Applikation für einen oder mehrere Coding-Standards gleichermaßen zu erhalten.

Das Internet der (un)sicheren Dinge

Das Internet der Dinge (IoT) wird auch in den nächsten Jahren stetig und sehr stark wachsen. Zu verlockend sind die Versprechungen, die es mit sich bringt: Effizienz, Kostensenkung, bessere Zusammenarbeit über miteinander verbundene Endgeräte. Gleichzeitig wachsen aber auch die Bedenken. Denn jede Verbindung kann zum Einfallstor für unerwünschte Angriffe werden – und ist damit ein Sicherheitsrisiko.

In guter Erinnerung ist noch der Vorfall im Sommer 2015, als zwei Security-Experten Live demonstrierten, wie sie per Hack die Kontrolle über einen modernen SUV während der Fahrt übernahmen und beispielsweise dessen Motor abstellten. Eindrucksvoll wurde gezeigt, wie ein eigentlich technologisch fortschrittliches System wie ein modernes High-End-Fahrzeug Ziel einer solchen Attacke werden kann – mit möglicherweise fatalen Folgen. Wie steht es dann wohl um die Sicherheit der vielen Millionen einfachen Endgeräte, die mit wenig Geld entwickelt wurden und die den größten Teil des Internets der Dinge ausmachen?

Bild 1: Zahl der bis 2019 geschätzen IoT-Geräte, aufgeteilt in Marktsegmente.
Bild 1: Zahl der bis 2019 geschätzen IoT-Geräte, aufgeteilt in Marktsegmente.
(Bild: Business Insider)

Das Bewusstsein für die Bedrohung der Sicherheit ist also schon länger vorhanden Was aber über weite Strecken immer noch fehlt, ist die Integration der Security als wesentliches Element in die Softwareentwicklung und die Geschäftsprozesse. Die Bedeutung, die die Safety heute schon hat, muss auch die Security bekommen. Die Security-Schwachstellen zeigen ganz deutlich: es gibt keinen Grund zur Gelassenheit angesichts der Anzahl und des Niveaus der Risiken.

Prozess-Level

Es kostet viel Zeit und erheblichen Aufwand, Prozesse so zu implementieren, die Security und Safety gleichermaßen berücksichtigen. Der dafür notwendige Ansatz muss naturgemäß ganzheitlich sein. Deshalb kann er auch nicht auf einzelne Abteilungen oder Entwicklungsphasen beschränkt werden. Der SUV-Hack, zum Beispiel, hat Mängel und Schwachstellen auf vielen unterschiedlichen Ebenen offengelegt, nicht nur in der Architektur oder der Serviceberechtigung, sondern auch bei den Algorithmen für die Passwort-Generierung und vielen anderen Bereichen. Wer seine Produktentwicklung auf wirklich sichere Beine stellen will, muss auf allen Ebenen Verfahren integrieren, die Security und Safety gleichermaßen stärken

Was aber passiert, wenn man den Fokus nur auf die Softwareentwicklung legt? Oder besser: Welche Wahl hat ein Entwickler, wenn er eine sicherheitskritische Anwendung entwickeln soll, die gleichzeitig alle notwendigen Security-Anforderungen erfüllt? Gehen wir einmal davon aus, dass sowohl in der Anforderungs-, als auch in der Designphase alles dafür Notwendige bereits umgesetzt wird, sollten wir uns Gedanken darüber machen, wie wir das in effiziente, hochintegrierte Software übertragen, die alle Security-Anforderungen erfüllt.

Der sicherheitskritische Ansatz

Für die funktionale Sicherheit gibt es zwei Referenzstandards: IEC61508 und davon abgeleitete Standards; DO178B/C und Begleitdokumente wie DO330.

IEC61508 bezieht sich auf die funktionale Sicherheit von sicherheitsrelevanten Systemen im Bereich Elektrik, Elektronik oder programmierbarer Elektronik (EEPE). Da der Standard bei allen sicherheitsrelevanten Systemen mit EEPE-Endgeräten angewendet wird, ist sein Umfang ziemlich breit. Fast alle großen sicherheitsrelevanten Industriestandards, die nicht mit der Luft- und Raumfahrttechnik verbunden sind, wurden von IEC61508 abgeleitet.

DO178C und die dazugehörigen Begleitdokumente DO330, DO331, DO332 und DO333 bilden den Standard für Applikationen der Luft- und Raumfahrttechnik (Avionik). Wer auch immer ein FAA-Zertifikat für ein kommerzielles Avionik-Projekt haben möchte, muss diesen Standard erfüllen.

DO178C bezieht sich viel mehr auf die Software als IEC61508; der Grad der Software-Security (IDAL – item development assurance level) ist bestimmt durch eine Sicherheitsbewertung und Risikoanalyse. Es gibt fünf Grade: von A (katastrophal) bis E (kein Effekt).

Wenn es um sicherheitskritische Anwendungen geht, ist klar definiert, was unter „kritischem Code“ zu verstehen ist. Es gibt standardisierte Methoden, um ihn zu qualifizieren. Wie der Entwicklungsprozess gestaltet werden muss, darüber gibt es klare Anweisungen. Safety integrity levels (SIL) in IEC61508, Automotive SIL (ASIL) in ISO26262, Software SIL (SSIL) in EN50128 oder IDAL in DO178C sind Beispiele für das gleiche Konzept. Dabei spielen Quantität und Qualität gleichermaßen eine Rolle: Wie stark verringert sich das Risiko für eine Funktion entsprechend der Risiko-Analyse? Und welche Aktionen werden unternommen, um sicherzustellen, dass der Qualitätslevel erreicht wird?

Nahezu alle in der Industrie anerkannten funktionalen Sicherheitsstandards schreiben vor, dass bestimmte Design- und Coding-Standards – abhängig vom jeweiligen SIL – übernommen werden. Einer der wichtigsten ist MISRA – selbst in Bereichen, wo er nicht zwingend vorgeschrieben ist. ISO26262-6 bestätigt für die Programmiersprache C, dass MISRA C viele Methoden abdeckt, die für das Design von Software-Units und deren Implementierung gefordert werden. Und das seine Verbreitung in alle wesentlichen sicherheitskritischen Softwarebereiche reicht, zum Beispiel im Maschinenbau, in der Medizintechnik, in der Kernkraft oder im Schienenverkehr.

Ganz ähnlich ist es bei DO178B/C. Diese Standards fordern eine sorgfältige Definition und Dokumentation des Softwareentwicklungsprozesses. Das Basis-Set aus geforderter Dokumentation und während der Laufzeit erstellten Artefakte beinhaltet umfangreiche und detaillierte Planungen – und ein Coding-Standard gehört mit dazu.

Bild 2: Software-Code-Standards bilden ein zentrales Element in der gesamten Software-Entwicklungskette.
Bild 2: Software-Code-Standards bilden ein zentrales Element in der gesamten Software-Entwicklungskette.
(Bild: QA Systems)

Coding-Standards wie MISRA definieren eine Teilmenge der Zielsprache. Das verhindert – oder begrenzt zumindest – den Einsatz von Merkmalen oder Konstrukten, die zu undefiniertem oder unspezifischem Verhalten führen könnten. Praktiken wie das Dulden von Dead Code oder nicht erreichbarem Code werden generell nicht zugelassen, da sie Probleme verursachen bei der Rückverfolgung und Überprüfung.

Wer einen Coding-Standard bei Applikationen mit hoher Integrität einsetzt, erhält fast automatisch Funktionen mit vorhersagbarem Verhalten. Ein Beispiel: Bei MISRA C: 2012 werden Entwickler davon abgehalten, dynamische Speicher zu verwenden. Der Grund: wer dynamische Speicher verwalten will, öffnet damit das Tor zu undefiniertem Verhalten, wenn er Standard-Bibliotheken falsch verwendet. Ohne MISRA C: 2012 muss man einen sehr hohen Aufwand betreiben, um nicht vorhersagbare Ergebnisse zu vermeiden.

Security für Anwendungen

ISO/IEC27001: 2003 legt die Anforderungen fest, wie ein Managementsystem zur Informationssicherheit aufgestellt sein muss und wie es eingeführt, gewartet und kontinuierlich verbessert werden kann. Es basiert auf dem PDCA-Modell (plan, do, check, act) und kann mit allen wichtigen Managementstandards geteilt werden. Noch detaillierter in Bezug auf Anwendungs-Security ist ISO/IEC27034: 2011. Dieser Standard bietet auch Anleitungen, wie Kontrollen zur Informations-Security definiert und eingeführt werden können – und das eingebunden in die Prozesse des Entwicklungszyklus’ des Systems.

Je näher wir sicherheitsorientierten Coding-Standards kommen, desto vielfältiger wird das Angebot: es gibt Sicherheitsstandards für die Kodierung in C und C++, aber auch in Java, Perl, PL/SQL und andere.

Es gibt eine große Vielfalt an verfügbaren Techniken, um Code-Security zu bewerten. Statische Analysen, dynamische und Laufzeitauswertungen, Datenfluss- und Kontrollfluss-Tracking oder ausführbare und heuristische Analysen können genutzt werden, um unterschiedlichen Fragen nachzuspüren. Diese Techniken können effektiv und einfach implementiert werden – sofern sie von der gewählten Sprache, den eingebauten Anlagen, den Bibliotheken etc. unterstützt werden.

Der wichtigste Bezugspunkt für Security- Coding-Standards ist CERT. Das Computer Emergency Response Team veröffentlich seit vielen Jahren Coding-Standards, um die Sicherheit von Software zu stärken. Die CERT- Coding-Standards bieten einen direkten Link zu Schwachstellen aus der realen Welt, die von der Organisation Common Weaknesses Enumeration (CWE) entdeckt worden sind. Die Liste der Schwachstellen (im Download verfügbar) kann nach spezifischen Beziehungskontexten durchsucht werden.

Das CWE wiederum ist verbunden mit einer breiter angelegten Sammlung öffentlich bekannter Schwachstellen der IT-Sicherheit – bekannt als CVE (Common Vulnerabilities and Exposures) – die heute den Standard darstellt, wenn es um das Identifizieren von Schwachstellen geht. CVE-IDs (Identifier) bieten Bezugspunkte für den Datenaustausch von IT-Security-Produkte und -Services. Sie sind dann besonders sinnvoll, wenn es um die Analyse-Abdeckung und die Effizienz von Tools und Services hinsichtlich spezifischer Klassen von Schwachstellen geht. Über 73.000 CVEs enthält die National Vulnerability Database von NIST (National Institute of Standards and Technology). Im NIST werden die Daten des standardbasierten Schwachstellenmanagements der US-Regierung gespeichert.

MISRA und CERT im direkten Vergleich

MISRA C:2012 und CERT C sind die Safety- und Security-Champions für die Programmiersprache C. Im Folgenden sehen Sie eine Gegenüberstellung.

 

http://www.misra.org.uk/graphics/misra_web_logo_small_f.gif

MISRA C:2012

CERTCM

CERT C

Review

Eingeschränkt (Working Group)

Offen und öffentlich (Website)

Structure

143 Regeln / 16 Directives

 

Regeln sind Richtlinien, für die eine vollständige Beschreibung der Anforderungen angeboten wird.

 

Im Gegensatz zu den Regeln bieten die Direktiven keine vollständige Beschreibung, so dass es nicht möglich ist, einen Compliance-Check durchzuführen.

 

98 Regeln / 178 Empfehlungen

 

Regeln müssen folgende drei Kriterien erfüllen:

1.        Das Verletzen der Richtlinien führt wahrscheinlich zu einem Sicherheitsfehler

2.        Es hängt nicht ab von Quellcode-Vermerken oder Annahmen zu Absichten der Programmierer

3.        Übereinstimmung mit den Richtlinien kann über automatisierte Analysen, formale Methoden oder manuelle Inspektionen bestimmt werden

Empfehlungen müssen zwei Kriterien erfüllen:

1.        Ihre Anwendung verbessert wahrscheinlich Safety, Verlässlichkeit oder Security der Softwaresysteme.

2.        Mindestens eine als Regel klassifizierte Anforderung kann nicht erfüllt werden.

Enforcement

Das Formulieren von Regeln ist auf Automatisierung ausgerichtet.

Beispiel:

Regel 8.14: "The restrict type qualifier shall not be used"

Das Formulieren von Regeln ist etwas allgemeiner gefasst.

Beispiel:

EXP43-C: "Avoid undefined behavior when using restrict-qualified pointers"

Organization

Ausgerichtet auf Sprachen und Entwicklungsumgebungen: “The Implementation”, “Compilation and build”, “Requirements traceability”, “Code design”, “A standard C environment”, “Unused code”, “Comments”, “Character sets and lexical conventions”, “Identifiers”, “Types”, “Literals and constants”, “Declarations and definitions”, “Initialization”, “The essential type model”, “Pointer type conversions”, “Expressions”, “Side effects”, “Control statement expressions”, “Control flow”, “Switch statement”, “Functions”, “Pointers and arrays”, “Overlapping storage”, “Preprocessing directives”, “Standard libraries” and “Resources”.

Ausgerichtet auf Low-Level-Elemente: “Preprocessor (PRE)”, “Declarations and initialization (DCL)”, “Expressions (EXP)”, “Integers (INT)”, “Floating Point (FLP)”, “Arrays (ARR)”, “Characters and strings (STR)”, “Memory management (MEM)”, “Input/Output (FIO)”, “Environment (ENV)”, “Signals (SIG)”, “Error handling (ERR)”, “Application Programming Interfaces (API)”, “Concurrency (CON)”, “Miscellaneous (MSC)”, “POSIX (POS)”, “Microsoft Windows (WIN)”

 

 

 

 

Severity classification

Locker verbunden mit der “Kategorie” der Regel:

·         Mandatory (Keine Abweichung erlaubt)

·         Required (Abweichungen erlaubt)

·         Advisory (kein formaler Abweichungsprozess erforderlich)

Konzept basiert auf Risikobeurteilung. Jede Richtlinie besitzt eine priority (Priorität) als Resultat aus severity, likelihood und remediation cost – Schwere des Vorfalls, Wahrscheinlichkeit und Behebungskosten (jede von ihnen bewertet auf einer Skala von 1 bis 3). Die Reichweite der Prioritäten legt einen von drei möglichen levels fest:

L1 -> Priorities 12, 18, 27 (high severity)

L2 -> Priorities 6, 8, 9

L3 -> Priorities 1, 2, 3, 4 (low severity)

 

Deviation procedure

Formalisiert: Anzeige erforderlich, von welcher Richtlinie abgewichen wurde, unter welchen Umständen die Abweichung erlaubt ist, eine Begründung für die Abweichung, eine Risikobeurteilung der Abweichung (aufzeigen, wie die Safety sichergestellt wird, ob zusätzliche Tests notwendig werden etc.) und es ist eine formelle Bestätigung nötig.

 

Limitierung: Es kann nur von Advisory und Required Rules abgewichen werden.

Es gibt keine Beschreibung für einen formalen Managementprozess für Abweichungen, obwohl sie als eine Möglichkeit genannt werden “true-positives” ((XX))

 

 

 

 

Wie man sieht, gibt es deutliche Unterschiede zwischen den Coding-Standards CERT und MISRA. Aber es ist durchaus möglich, eine Strategie festzulegen, die es möglich macht, beide Standards in derselben Codebasis sinnvoll zu nutzen. Tools wie die von PRQA sind der effektivste Weg, eine solche Strategie in den Entwicklungsprozess zu implementieren. Diese Tools bilden die Basis für eine Tiefenanalyse des Software-Codes, um Fehler zu vermeiden, zu entdecken und zu beseitigen. Gleichzeitig erzwingen sie Kodierungsregeln, die die Software-Compliance sicherstellen. Und: Als Zusatznutzen sorgen sie für die bessere Wartbarkeit der Software – das senkt die Kosten für die Entwicklung auf breiter Front.

Zusammenfassend lässt sich sagen: Es kann eine große Herausforderung sein, sicherheitskritische Software zu entwickeln, die höchste Security-Ansprüche erfüllt. Safety und Security erfordern einen ganzen Katalog an Strategien, Prozessen, Tools und Fähigkeiten, die sich nicht überschneiden oder gar gegenseitig beeinträchtigen sollen. Automatisierte Analyse-Tools sind ein effektiver Weg innerhalb einer ganzheitlichen Betrachtung, Fehler im Code zu vermeiden – die sonst zu Sicherheitsproblemen und Security-Schwachstellen führen könnten.

* Richard Bellairs ist Product Marketing Manager bei PRQA.

(ID:44958291)