Im November 2022 veröffentlichte die National Security Agency der Vereinigten Staaten ein Bulletin, das ein klares Statement zum sicheren Umgang mit Arbeitsspeichern (RAM) setzt. Werfen wir einen Blick auf andere NSA-Bulletins, stellen wir fest, dass diese sich in den meisten Fällen auf die Datenverschlüsselung oder den Schutz von Produktionsschleifen und andere organisatorische Fragen konzentrieren. Dass sich die NSA direkt an Softwareentwickler wendet, ist recht ungewöhnlich. Deshalb scheint es sich in diesem Ausnahmefall um ein besonders wichtiges Thema zu handeln. Im Grunde genommen fordert die NSA Softwareentwickler dazu auf, Programmiersprachen zu verwenden, deren Architektur eine höhere Sicherheit bei der Speicher-Arbeit bietet. Der Einsatz von C und C++ soll vor diesem Hintergrund vermieden werden. Darüber hinaus wird empfohlen, eine Reihe von Maßnahmen zu ergreifen, um Software auf Schwachstellen zu testen und deren Exploit zu verhindern.
Für Programmierer sind diese Dinge offensichtlich, und die Forderungen der NSA richten sich nicht direkt an sie, sondern an Unternehmensleitungen und -Vertreter. Lassen Sie uns, ohne auf technische Details einzugehen, die vorgebrachten Argumente analysieren.
Speichersicherheit
Werfen wir zunächst einen Blick auf unseren jüngsten Bericht über die Bedrohungsentwicklung im 3. Quartal 2022 und die Schwachstellen, die am häufigsten für Cyberangriffe genutzt werden. An erster Stelle steht nach wie vor die 2018 entdeckte Schwachstelle CVE-2018-0802 in der Komponente Equation Editor der Microsoft Office-Suite. Sie wird durch eine fehlerhafte Datenverarbeitung im RAM-Speicher verursacht, wodurch das Öffnen eines bösartigen Microsoft Word-Dokuments zur Ausführung von beliebigem Code führen kann. Eine weitere bei Cyberkriminellen beliebte Sicherheitslücke ist CVE-2022-2294 in der WebRTC-Komponente des Google Chrome-Browsers. Sie führt aufgrund eines Pufferüberlauffehlers zur Ausführung von beliebigem Code. Eine weitere Sicherheitslücke – CVE-2022-2624 – im PDF-Viewer-Tool von Chrome kann ebenfalls zu einem Pufferüberlauf führen.
Natürlich sind nicht alle Software-Schwachstellen auf eine unzureichend gesicherte Handhabung des Arbeitsspeichers zurückzuführen, aber viele. Das NSA-Bulletin zitiert Statistiken von Microsoft, wonach Fehler bei der Speicherverwaltung 70 % der entdeckten Schwachstellen verursachen.
Aber warum passiert so etwas? Wenn Speicherlecks ein so ernsthaftes Problem darstellen, warum hören wir dann nicht einfach auf, anfälligen Code zu schreiben? Die Wurzel des Problems liegt in der Verwendung der Programmiersprachen C und C++. Ihre Architektur bietet Entwicklern viel Freiheit bei der RAM-Arbeit. Doch Freiheiten bringen immer auch Verantwortung mit sich. C/C++-Programmierer müssen selbst Mechanismen für das sichere Schreiben und Lesen von Daten implementieren. Andere hochrangige Programmiersprachen wie C#, Rust, Go und andere kümmern sich jedoch automatisch darum. Der Punkt ist, dass beim Kompilieren des Programmquellcodes die Mittel für eine sichere Speicherhandhabung automatisch eingeführt werden und die Entwickler keine Zeit mehr dafür aufwenden müssen. Um die Sicherheit zu verbessern, ergreift Rust zum Beispiel noch mehr Sicherheitsmaßnahmen; dazu zählt unter anderem die Kompilierungsparalyse von potenziell gefährlichem Code und das Anzeigen von Fehlern für Programmierer.
Natürlich ist es nicht realistisch, einfach auf C/C++ zu verzichten, solange diese Sprachen für bestimmte Aufgaben unverzichtbar bleiben, beispielsweise wenn Code für MCUs oder andere Geräte mit stark eingeschränkter Rechenleistung und Speichergröße benötigt wird. Unter sonst gleichen Bedingungen können hochrangigere Programmiersprachen des Weiteren zur Entwicklung von ressourcenintensiveren Programmen führen. Doch die allgemeinen Bedrohungsstatistiken zeigen, dass Angriffe meist auf gewöhnliche Anwendersoftware (wie Browser und Texteditoren) abzielen, die auf sehr leistungsfähigen Computern läuft (im Vergleich zu MCUs).
Der Wechsel zu einer neuen Programmiersprache ist nicht ganz leicht
Dessen ist sich die NSA bewusst. Eine große Datenbank mit Software, die in einer „unsicheren“ Programmiersprache geschrieben wurde, kann nicht über Nacht in eine andere Sprache portiert werden. Selbst wenn es darum geht, ein Softwareprodukt von Grund auf neu zu schreiben, kann es durchaus ein etabliertes Team, eine Infrastruktur und Entwicklungsmethoden für eine bestimmte Programmiersprache geben.
Zum Vergleich: Stellen Sie sich vor, Sie müssten aus Ihrem Haus ausziehen, nur weil es alt ist. Sie wissen jedoch, dass das Gebäude absolut massiv ist und nur im Fall eines starken Erdbebens einstürzen würde. Dazu kommt, dass Sie selbstverständlich daran gewöhnt sind, dort zu leben – schließlich ist es Ihr Zuhause. In einem Beitrag stellt das Entwicklerteam von Google Chrome klar, dass es derzeit nicht möglich ist, auf eine andere Programmiersprache mit integriertem Schutz (in diesem Fall Rust) umzusteigen. Dies könnte in Zukunft möglich werden. Aber im Hier und Jetzt ist eine andere Lösung erforderlich.
Im selben Beitrag der Google Chrome-Entwickler wird auch erklärt, warum man die Sicherheit von C/C++-Code nicht grundlegend ändern kann. Diese Programmiersprachen wurden schlichtweg nicht dafür entwickelt, alle Kompilierungsprobleme auf einen Schlag zu lösen. Aus diesem Grund werden im NSA-Bulletin zwei Alternativmaßnahmen genannt:
- Die Prüfung des Codes auf potenzielle Schwachstellen mit dynamischen und statischen Analysetechniken;
- Der Einsatz von Funktionen, die den Exploit von fehlerhaftem Code vorbeugen.
Die Herausforderungen einer Umstellung
Im Großen und Ganzen stimmen Tech-Experten mit der Meinung der NSA überein. Beim „Wie?“ in Bezug auf den Übergang zu hochrangigeren Programmiersprachen können die Meinungen jedoch stark auseinandergehen, wenn sich die Notwendigkeit dafür unter anderem aus Sicherheitsanforderungen ergibt. Zunächst muss man sich darüber im Klaren sein, dass eine solche Umstellung viele Jahre in Anspruch nehmen kann und nicht von jetzt auf gleich passiert. Darüber hinaus hat eine solche Entwicklung ihren Preis – den nicht jedes Unternehmen bereit ist zu zahlen. Das Problem beim Umgang mit unsicherem Arbeitsspeicher in Programmiersprachen mit niedrigem Abstraktionslevel ist systembedingt. Der Schrei nach einer radikalen Lösung ist notwendig, dennoch ist nicht zu erwarten, dass morgen jeder auf die Entwicklung in C#, Go, Java, Ruby, Rust oder Swift umsteigt. Genauso wenig wie man eine ganze Stadt oder ein ganzes Land dazu bringen kann, von heute auf morgen zum Vegetarismus oder einer anderen extremen Veränderung überzugehen.
Aus Unternehmenssicht ist es sinnvoll, sowohl in neue Technologien zu investieren (durch die Entwicklung von Fähigkeiten und die Einstellung erfahrener Fachleute) als auch den Schutz bestehender Technologien zu maximieren. Im Rahmen der Softwareentwicklung können zudem neue Programmiersprachen und Technologien zum Testen von vorhandenem Code berücksichtigt werden. Alle anderen Unternehmen können unterstützend handeln, indem sie beispielsweise in neue Technologien zum Schutz vor Cyberangriffen investieren, aber auch die Stärke ihrer bestehenden Infrastruktur regelmäßig überprüfen. Mit anderen Worten: Ein umfassender Sicherheitsansatz ist optimal und wird es auch noch lange bleiben.