Auf Nummer sicher: Sicheres Programmieren mit Rust

Die Programmiersprache Rust hat sich als Alternative zu C/C++ etabliert. Was macht Rust in puncto Sicherheit anders und vielleicht besser als die Platzhirsche?

In Pocket speichern vorlesen Druckansicht 737 Kommentare lesen

(Bild: Andrew Derr/Shutterstock.com)

Lesezeit: 17 Min.
Von
  • Jens Siebert
Inhaltsverzeichnis

Betrachtet man die Geschichte der System-Programmierung über die letzten Jahrzehnte, mit dominierenden Programmiersprachen wie C oder C++, so fällt vor allem eines auf: Fehlerfreiheit oder Informationssicherheit werden oft erst im Nachgang zur Implementierung einer Anwendung oder als Prozess-Themen betrachtet.

Insbesondere für Anwendungen, die Standards für sicherheitskritische Systeme entsprechen müssen, wird eine hohe Testabdeckung sowie die Anwendung statischer Codeanalyse empfohlen oder vorgeschrieben. Das ist unter anderem in der Medizintechnik oder im Banken- und Finanzwesen der Fall.

Sonderheft zu sicherer Softwareentwicklung

Dieser Artikel stammt aus dem neuen iX-Developer-Sonderheft "Sichere Software entwickeln". Es behandelt auf 156 Seiten unter anderem die Themen Web-Application-Security, Codeanalyse und Cloud-Security.

Der Schwerpunkt zu den Programmiersprachen zeigt die Sicherheitskonzepte von Rust auf und ein weiterer Artikel hilft, Speicherfehler in C++ aufzuspüren sowie zu vermeiden. Wer mit Java entwickelt, findet eine Übersicht der Änderungen an der Security von Java 11 bis Java 17.

Der Themenbereich Kryptografie geht von den Grundlagen über die Fallstricke beim Einbinden kryptografischer Verfahren in eigene Anwendungen bis zum Ausblick auf die Post-Quanten-Kryptografie. Ein weiterer Schwerpunkt zu DevSecOps zeigt Methoden, Werkzeuge und Reifegradmodelle auf.

Das Heft ist ab sofort im heise Shop als PDF für 12,99 Euro verfügbar. Die gedruckte Ausgabe lässt sich für 14,90 Euro vorbestellen. Ein Bundle aus gedruckter Ausgabe plus PDF ist ebenfalls verfügbar.

Eine der Ursachen für solche Empfehlungen und Vorgaben ist in den verwendeten Programmiersprachen zu suchen. Sowohl C als auch das abwärtskompatible C++ erlauben es, ihre Konstrukte so einzusetzen, dass sie zu undefiniertem Verhalten eines Programms führen können (s. Listing 1).

int main() {
    unsigned long a[1];
    a[3] = 0xaaaabbbbdeadbeefUL;
    return 0;
}

Listing 1: Syntax-Highlighting in C

Dieses standardkonforme, jedoch offensichtlich fehlerhafte Beispiel lässt sich von jedem C/C++-Compiler in ein ausführbares Programm übersetzen und ausführen. Das Verhalten des Programms ist gemäß dem C/C++-Standard undefiniert:

"Undefined Behavior: Behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements." (Aus der Spezifikation: ISO/IEC 9899:2018, Kapitel 3.)

Implementierungen dieser Standards ist es freigestellt, wie sie mit undefiniertem Verhalten umgehen. Im besten Fall erkennt der Compiler die Gefahr und gibt eine Warnung oder gar einen Fehler aus, oder es passiert wie in den meisten Fällen einfach nichts. Das öffnet Tür und Tor für unbeabsichtigte Fehler und Sicherheitslücken, die in unserer stark vernetzten Welt umso stärker zum Tragen kommen, wie man beinahe täglich den (IT-)Nachrichten entnehmen kann.

Hier schlägt oft die Stunde von Werkzeugen zur statischen Codeanalyse, die in der Lage sind, solche Fehler zu erkennen. Jedoch sind diese Werkzeuge meist recht teuer in der Anschaffung und müssen erst aufwendig in den Entwicklungsprozess integriert werden. Prinzipbedingt erkennen sie bei Weitem nicht alle potenziellen Fehler.

Sinnvoller wäre es, eine System-Programmiersprache von vornherein so zu entwerfen, dass sie undefiniertes Verhalten weitestgehend unterbindet. Mit diesem Anspruch wird die Programmiersprache Rust seit 2010 von einer internationalen Open-Source-Community vorangetrieben. Zunächst als Projekt des Entwicklers Graydon Hoare bei der Mozilla Corporation gestartet und durch sie unterstützt, erfreut sich die Sprache mittlerweile wachsender Beliebtheit. Auch große Player wie beispielsweise Microsoft oder Amazon nutzen und unterstützen Rust.

Das Ziel der Entwicklung von Rust war von Beginn an, eine Programmiersprache zu entwickeln, die die Themen Sicherheit (Safety), Geschwindigkeit (Performance) und Nebenläufigkeit (Concurrency) unter einen Hut bringt und dabei so benutzerfreundlich wie möglich bleibt. Zur Umsetzung dieser Ziele implementiert Rust verschiedene Konzepte, die im Folgenden näher betrachtet werden sollen.