Werden Sie gerade angegriffen? Hilfe bei der Vorfallsbehandlung

info@angelforce.eu
Sichere Entwicklung

Memory-Safety-Roadmap für C und C++ ohne vollständigen Rewrite

Wie Produktteams das Memory-Safety-Risiko in C und C++ noch dieses Quartal senken: mit Inventar, Isolation, Fuzzing und kurzer Rewrite-Liste.

Auch verfügbar auf:EnglishTürkçeFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: Memory-Safety-Roadmap für C und C++ ohne vollständigen Rewrite

Eine Memory-Safety-Roadmap ist ein Plan mit Verantwortlichen und Terminen. Sie können sie noch in diesem Quartal schreiben, ohne den Großteil Ihres C- und C++-Codes anzufassen. Der Rewrite kommt später und betrifft nur die Teile, die ihn rechtfertigen. Jetzt brauchen Sie ein klares Bild davon, wo unsicherer Code liegt, eine Möglichkeit, ihn einzugrenzen, und eine Dokumentation Ihrer Entscheidungen.

CISAs The Case for Memory Safe Roadmaps beschreibt, wie Softwarehersteller auf speichersichere Sprachen (Memory Safe Languages, MSLs) umsteigen können, um Memory-Safety-Schwachstellen zu beseitigen. Hersteller sollen Roadmaps veröffentlichen, damit Kunden sehen, wie sie Verantwortung für Sicherheitsergebnisse übernehmen, radikale Transparenz leben und einen Top-down-Ansatz verfolgen. Das sind Grundsätze von Secure by Design, und das Dokument richtet sich ebenso an die Führungsebene wie an Engineers. Dieses zweite Publikum ist wichtig: Eine Roadmap ohne Sponsor bleibt im Wiki liegen.

Was die Quellen abdecken und was nicht

Die Zusammenfassungsseite der CISA erwähnt nur den Umstieg auf MSLs sowie die Erstellung und Veröffentlichung einer Roadmap. Den vollständigen Inhalt zeigt sie nicht, deshalb treffen wir keine Aussage dazu, was das Dokument zu Fuzzing oder Prozessisolation sagt. Diese beiden Schritte unten sind unsere eigene Praxis für die Jahre zwischen „Wir haben heute C++“ und „Wir haben in den kritischen Teilen eine sicherere Sprache“. Verstehen Sie sie als Übergangsmaßnahmen, nicht als Ersatz für die Roadmap.

Zahlen dazu, wie viel Risiko ein Schritt jeweils beseitigt, liefern die Quellen ebenfalls nicht. Wir erfinden keine. Messen Sie es selbst, anhand Ihrer eigenen Absturz- und Schwachstellenhistorie.

Schritt 1: Unsicheren Code inventarisieren

Was Sie nicht aufgelistet haben, können Sie nicht priorisieren. Legen Sie die Tabelle pro Komponente an, nicht pro Repository, denn ein Repository enthält oft ein unkritisches Hilfsprogramm neben einem Netzwerk-Parser.

FeldWarum es wichtig ist
Sprache und StandardZeigt, was sich migrieren lässt und was nicht
Von außen erreichbar?Netzwerk, Datei, USB, serielle Schnittstelle, Update-Kanal
Verarbeitet nicht vertrauenswürdige Eingaben?Bestimmt die Priorität für Fuzzing und Rewrite
Mit welchen Rechten läuft sie?Bestimmt, wie viel Isolation bringt
Drittanbieter oder eigener Code?Bestimmt, wer den Fehler beheben kann
Verantwortliche Person und letzte substanzielle ÄnderungToter Code lässt sich oft entfernen

Nehmen Sie Vendored Libraries und Firmware-Komponenten auf. Gerade Hardware-Teams haben häufig alten C-Code in Bootloadern, Treibern und Update-Handlern, den seit Jahren niemand geöffnet hat. Auch diese Komponenten verdienen eine Zeile.

Schritt 2: Isolieren, was Sie noch nicht ersetzen können

Fragen Sie sich für jede Komponente, die als erreichbar markiert ist und nicht vertrauenswürdige Eingaben verarbeitet: Was passiert, wenn sie vollständig kompromittiert wird? Lautet die Antwort „alles“, ist das Ihre erste Designänderung. Verlagern Sie den Parser in einen eigenen Prozess, entziehen Sie ihm Rechte und nehmen Sie ihm den Zugriff auf Dateien, Sockets und Schlüssel, die er nicht braucht.

Das behebt den Fehler nicht. Es begrenzt, was der Fehler für einen Angreifer wert ist. Das entspricht dem Ziel des Secure Software Development Framework (SP 800-218) des NIST, die möglichen Auswirkungen der Ausnutzung von Schwachstellen abzuschwächen, die Sie noch nicht gefunden haben.

Schritt 3: Einstiegspunkte fuzzen

Nehmen Sie die Komponenten aus Ihrem Inventar, die nicht vertrauenswürdige Eingaben verarbeiten, und schreiben Sie für jede ein Fuzz-Harness. Lassen Sie die Harnesses in der CI mit einem Zeitbudget laufen und bewahren Sie das Crash-Korpus auf. Beginnen Sie mit Dateiformaten, Protokollnachrichten und Update-Paketen, denn das sind die Wege, die ein Außenstehender erreichen kann.

Bauen Sie die Fuzzing-Binaries mit aktivierter Speicherfehlererkennung des Compilers, damit aus einem stillen Overread ein sichtbarer Fehler wird. Jeder Crash, den Sie analysieren, liefert etwas, das die Roadmap braucht: Belege dafür, welche Komponenten einen Rewrite verdienen. Findet ein Harness auch nach längeren Läufen nichts, ist das ebenfalls nützlich, denn dann können Sie diese Komponente niedriger einstufen.

Schritt 4: Eine kurze Rewrite-Liste wählen

Wählen Sie anhand der ersten drei Schritte die Kandidaten aus. Ein guter erster Rewrite hat diese Eigenschaften:

  • Er verarbeitet nicht vertrauenswürdige Eingaben.
  • Er hat eine schmale Schnittstelle, sodass er hinter derselben API ersetzt werden kann.
  • Er hat beim Fuzzing Abstürze verursacht oder hat eine Fehlerhistorie.
  • Er ist klein genug, dass ein Team ihn in ein bis zwei Release-Zyklen abschließen kann.

Lassen Sie stabilen, internen, nicht exponierten Code in C oder C++ und halten Sie das in der Roadmap fest. „Nicht geplant, isoliert, gefuzzt“ neben einer Komponente zu notieren, ist ehrlich, und Kunden können damit arbeiten. Das ist unsere Auslegung von radikaler Transparenz: Sie benennen Ihre Position, und nicht jede Zeile muss in einem Rewrite enden. Die Zusammenfassung der CISA nennt den Grundsatz, sagt aber nicht, was er für Komponenten bedeutet, die in C oder C++ bleiben.

Neue Komponenten sind der günstigste Ausgangspunkt. Entscheiden Sie jetzt, welche Sprache neuer netzwerkfähiger Code verwenden wird, und schreiben Sie das in Ihre Engineering-Standards.

Schritt 5: Schriftlich festhalten und im Prozess verankern

Das NIST beschreibt das SSDF als Kernsatz übergeordneter Praktiken, den Sie in den Entwicklungslebenszyklus integrieren, den Sie ohnehin betreiben, mit dem Ziel, Ursachen anzugehen, damit Schwachstellen nicht wiederkehren. Verankern Sie Ihre Memory-Safety-Regeln in diesem bestehenden Prozess: Sprachwahl für neuen Code, Fuzzing in der CI, ein Review-Gate für unsichere Konstrukte. Das SSDF gibt außerdem Käufern und Lieferanten ein gemeinsames Vokabular, was hilft, wenn der Sicherheitsfragebogen eines Kunden nach Memory Safety fragt.

Für Coding-Checklisten ist das Projekt OWASP Secure Coding Practices Quick Reference Guide archiviert. Seine Checklisten sind in den OWASP Developer Guide übergegangen. Nutzen Sie diese Fassung statt eines veralteten PDFs.

Wo Sie anfangen

  1. Exportieren Sie eine Liste aller C- und C++-Komponenten, einschließlich Vendored Code und Firmware, und füllen Sie die obige Inventartabelle aus. Begrenzen Sie das auf zwei Wochen.
  2. Markieren Sie die Komponenten, die nicht vertrauenswürdige Eingaben lesen, und notieren Sie, worauf jede im Kompromittierungsfall zugreifen kann.
  3. Legen Sie die drei wichtigsten exponierten Komponenten in separate Prozesse mit minimalen Rechten oder planen Sie die Änderung mit einer namentlich benannten verantwortlichen Person ein.
  4. Schreiben Sie Fuzz-Harnesses für genau diese Komponenten und lassen Sie sie in der CI laufen. Prüfen Sie die Abstürze wöchentlich.
  5. Wählen Sie eine Komponente für den Rewrite in einer speichersicheren Sprache aus und legen Sie eine Sprachregel für sämtlichen neuen netzwerkfähigen Code fest.
  6. Veröffentlichen Sie eine einseitige interne Roadmap mit Verantwortlichen und Terminen und entscheiden Sie dann, was Sie mit Kunden teilen. Wenn Sie eine externe Prüfung wünschen, können unser Service für sichere Softwareentwicklung und unsere Penetrationstests das Inventar prüfen und die isolierten Komponenten testen.

So können wir helfen

Sichere Software

Wir verankern Sicherheit in Software ab dem ersten Commit und entwickeln eigene Sicherheitstools.

Schreiben Sie uns
AngelForce-Team

Geschrieben vom AngelForce-Team: Sicherheitsberater mit CEH-, LPT-Master- und CISA-Zertifizierung, die Systeme von Organisationen in ganz Europa und in der Türkei testen, überwachen und schützen.

Mit KI-Unterstützung auf Grundlage der unten aufgeführten öffentlichen Quellen verfasst und vor der Veröffentlichung vom AngelForce-Team geprüft.

Quellen

  1. www.cisa.gov/resources-tools/resources/case-memory-safe-roadmaps
  2. csrc.nist.gov/pubs/sp/800/218/final
  3. owasp.org/projects/secure-coding-practices-quick-reference-guide

Artikel zum Thema Sichere Entwicklung

Sagen Sie uns, was Sie schützen müssen

Beschreiben Sie Ihre Umgebung und was Sie erreichen möchten. Wir antworten per E-Mail.

Schreiben Sie uns
info@angelforce.eu

AngelForce OÜ · Tallinn, Estland