Rust verfügt über zahlreiche Mechanismen, die Entwickler dabei unterstützen, Fehler sowie Sicherheitsschwachstellen zu vermeiden. Dennoch ist auch hiermit eine robuste Safety und Security nicht garantiert. Wer sichere Software in Rust entwickeln möchte, sollte die folgenden Dos & Don'ts beachten.
Die Programmiersprache Rust garantiert Speichersicherheit zur Compile-Zeit und wird zunehmend für die Entwicklung von eingebetteten Systemen genutzt. Dennoch zeigt die Praxis, dass auch unter der Anwendung von Rust vielfältige Sicherheitsprobleme auftreten können. Wir geben einen Überblick über die Dos and Don'ts bei der Umsetzung von sicherheitsrelevanten Funktionen mit Rust.
(Bild: KI-generiert / DALL-E)
Angesichts der weiter zunehmenden Vernetzung von Systemen und der kommenden Regularien der Europäischen Union (EU), allen voran der Cyber Resilience Act und die EU-Maschinenverordnung, werden die Erhöhung der Angriffssicherheit (Security) und die Vermeidung von negativen Auswirkungen von Security-Vorfällen auf die funktionale Sicherheit (Safety) von eingebetteten Systemen essenziell. Der Cyber Resilience Act verlangt von Softwareherstellern ein effektives Security Testing, um Sicherheitslücken zu vermeiden.
Die derzeit am häufigsten offengelegten Sicherheitslücken sind sogenannte Speicher-Sicherheitslücken. [1, 2, 3, 4, 5]. Sie treten auf, wenn eine Software den Arbeitsspeicher manuell verwaltet und sich dabei ein Softwarefehler einschleicht. Diese Sicherheitslücken führen oft zu Programmabstürzen, wie beispielsweise im Falle des kürzlich aufgetretenen Fehlers in der Software Crowdstrike Falcon [6] und werden von böswilligen Akteuren routinemäßig für kriminelle Handlungen ausgenutzt (Stichwort Cybercrime). Softwarehersteller sind dadurch gezwungen, ständig Sicherheitsupdates zu veröffentlichen und Kunden müssen kontinuierlich Patches einspielen. Historische Bemühungen der Softwarehersteller dieses Problem mithilfe von Security Testing, Security Patches oder Schulungen zu lösen, konnten das Problem bisher nicht gänzlich ausmerzen. Die Softwareindustrie setzt deshalb vermehrt auf Sprachen, die von Haus aus speichersicher sind, wie beispielsweise die Sprache Rust.
Sicherheit in Rust
Die Sprache Rust ist bekannt für ihr starkes Typsystem, welches Speichersicherheit und Thread-Sicherheit zur Compile Zeit sicherstellt. Rust verwendet keinen Garbage Collector und gewinnt deshalb auch für die Entwicklung eingebetteter Systeme an Bedeutung.
Die Sicherheit in Rust beruht darauf, dass der Compiler eine Reihe von Einschränkungen erzwingt: Er verbietet beispielsweise unsichere Pointer-Operationen sowie mehrere schreibbare Referenzen auf dieselbe Speicherstelle. Außerdem sind veränderliche globale Variablen standardmäßig verboten.
Die Praxis hat gezeigt, dass Entwickler trotz dieser drastischen Einschränkungen viele Probleme in Rust ausdrücken können. Es lässt sich jedoch nicht jedes Problem im Rahmen dieses sicheren Typsystems ausdrücken und für spezielle Fälle bietet Rust eine Unsafe-Sprache, welche diese Restriktionen aufhebt und potenziell gefährliche Operationen erlaubt. Der Programmierer ist nun wieder selbst in der Verantwortung, dass die Regeln der Sprache eingehalten werden und undefiniertes Verhalten verhindert wird. Schlimmer noch: Das starke Typsystem von Rust beruht auf weitaus mehr Regeln als beispielsweise das von C++. Daher muss man beim Einsatz von Unsafe Rust umso mehr aufpassen, dass keine dieser Rust-Regeln verletzt wird, denn der restliche Safe Rust Code verlässt sich auf diese Regeln. Nachfolgend beschreiben wir, mit welchen Werkzeugen es dennoch möglich ist, sicher mit Rust zu entwickeln.
Dos and Don'ts für die Entwicklung mit Unsafe Rust
Unsafe Rust sollte nicht eingesetzt werden, wenn es eine sichere API für die gesuchte Funktionalität gibt. Die Rust Standard-Bibliothek bietet bereits viele sichere APIs an, welche intern zwar teils Unsafe Rust nutzen, für die die Korrektheit aber sichergestellt wurde. Zusätzlich gibt es viele Rust-Bibliotheken, die ebenfalls Unsafe Rust kapseln und über eine sichere API anbieten. Es lohnt sich daher ein Blick in die Rust Package Registry [7], welche derzeit ca. 160.000 Open-Source Softwarepakete bereitstellt.
Schreibt man Unsafe Rust selbst, so empfiehlt es sich, den Code mit entsprechender Sorgfalt zu pflegen. Dabei hat sich im Rust Ecosystem der Ansatz des „Interior Unsafe“ [8] also gekapseltem Unsafe Code durchgesetzt. Demnach sollte man den Unsafe Rust Code möglichst in eine eigene Funktion oder ein eigenes Projekt auslagern, um ihn besser separat warten zu können. Außerdem können Werkzeuge genutzt werden, die bei der sicheren Entwicklung unterstützen.
Werkzeuge zum Erkennen von Schwachstellen im eigenen Code
Das Werkzeug Miri [9] führt eine dynamische Analyse des Programms durch, die den Quellcode interpretiert und so zur Laufzeit ungültige Speicherzugriffe, Speicherleaks sowie undefiniertes Verhalten identifiziert. Treten Fehler auf, so kann Miri auf das Problem hinweisen. Miri wurde bereits erfolgreich eingesetzt, um Fehler in einer Reihe von bestehenden Rust Projekten aufzudecken.
Das Werkzeug Cargo Fuzz [10] kann verwendet werden, um Rust Programme mithilfe eines Fuzzers zur Laufzeit zu analysieren. Der Fuzzer führt das Programm mit exotischen Parametern aus mit dem Ziel, ungetestete Pfade auszuführen, die das Programm zum Absturz bringen. Gelingt dies, so wird der Fehler dem Nutzer berichtet.
Das Werkzeug MirChecker [11] durchsucht den Rust Quellcode nach Fehlern mithilfe einer statischen Analyse. Anders als der Rust Compiler bezieht es dabei aber explizit auch Speicherfehler im Unsafe Rust mit ein.
Das Werkzeug MIRAI [12] findet vergleichbare Fehler im Rust Quellcode, unterstützt aber auch eine Timing-Analyse, die genutzt werden kann, um Seitenkanal-Schwachstellen zu identifizieren. Diese Schwachstellen ermöglichen es, Rückschlüsse auf interne Programmabläufe zu ziehen und wurden bereits eingesetzt [13], um einen geheimen Schlüssel aus einem Security Token zu extrahieren.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
Das Werkzeug Rudra [14] führt ebenfalls eine statische Analyse durch, fokussiert aber auf spezielleren Klassen von Problemen im Kontext von Unsafe Rust: Es erkennt beispielsweise fehlerhafte Programmzustände, wenn ein Programmabbruch (Panic) innerhalb von Unsafe Code auftritt.
Die genannten Werkzeuge zur Erkennung von Schwachstellen im eigenen Code sind Open Source und frei verwendbar. Miri und Cargo Fuzz führen das Programm aus und können deshalb nur Fehler identifizieren, in die das Programm zur Laufzeit hineinläuft. Die anderen Werkzeuge erkennen Fehler im Quellcode und ermöglichen daher eine bessere Abdeckung, können aber potenziell Fehlmeldungen liefern. Wir empfehlen für die Entwicklung von sicherheitskritischer Software die Verwendung aller genannten Werkzeuge.
Werkzeuge zum Erkennen von Schwachstellen in Softwareabhängigkeiten
Fehler in Softwareabhängigkeiten können sich auf alle Programme auswirken, die sie verwenden. Es gibt Werkzeuge, die Fehler in Abhängigkeiten erkennen können.
Das Werkzeug Cargo Geiger [15] identifiziert Unsafe Code in Softwareabhängigkeiten. Dadurch wird es möglich, Abhängigkeiten danach auszuwählen, ob und wieviel Unsafe Code sie enthalten.
Die RustSec Datenbank [16] dokumentiert bekannte Fehler in veröffentlichten Rust Bibliotheken und wird von Security Testing Werkzeugen teils automatisiert genutzt, um auf die problematische Nutzung fehlerhafter Bibliotheken hinzuweisen. Beispielsweise führte ein Speicherfehler in der viel-genutzten Rust-Bibliothek bumpalo zu einer Use-After-Free Vulnerability [17]. Die RustSec Datenbank dokumentiert sowohl die betroffenen Versionen der Bibliotheken, sowie die verwundbaren Funktionen.
Das Werkzeug Cargo Audit [18] kann genutzt werden, um die genutzten Abhängigkeiten eines Rust Projektes in der RustSec Datenbank zu suchen. Es meldet, wenn genutzte Bibliotheken von Schwachstellen betroffen sind. Falls eine verwendete Bibliothek eine bekannte Sicherheitsschwachstelle hat, so wird dem Nutzer empfohlen auf eine Version zu updaten, die den Fehler nicht mehr enthält – falls eine solche Version existiert. Cargo Audit überprüft allerdings nicht, ob der Rust Code die fehlerhafte Funktion überhaupt aufruft. Dennoch ist das Werkzeug hilfreich, um auszuschließen, dass Abhängigkeiten genutzt werden, für die Schwachstellen bekannt sind.
Das Werkzeug OSV-Scanner [19] von Google findet ebenfalls Softwareabhängigkeiten mit bekannten Schwachstellen. Es unterstützt aber auch eine experimentelle Funktionalität, die den Quellcode analysiert, um herauszufinden, ob die verwundbare Funktion überhaupt aufgerufen wird. Dies kann bei der Entscheidung unterstützen, ob der Quellcode tatsächlich verwundbar ist oder nicht.
Das Fraunhofer IEM entwickelt im Rahmen von Forschungsprojekten das Werkzeug Cargo Flowcheck. Ziel ist es, eindeutig zu erkennen, ob ein Rust Programm eine von Angreifern ausnutzbare Schwachstelle hat oder nicht. Cargo Flowcheck prüft dafür die Softwareabhängigkeiten und durchleuchtet den Quellcode intensiv, indem es dabei auch mögliche Belegungen von Variablenwerten einbezieht. So lässt sich präziser entscheiden, ob das Programm verwundbar ist oder nicht. Dies kann einem Softwareentwickler helfen, die Kritikalität einer Verwundbarkeit einzustufen und beispielsweise zu entscheiden, ob ein Security Patch dringend notwendig ist oder ob ein Fix im Zuge der nächsten stabilen Version ausreicht.
Die genannten Werkzeuge zur Erkennung von Schwachstellen in Softwareabhängigkeiten sind Open Source und frei verwendbar und wir empfehlen deren Nutzung. Die Wahrscheinlichkeit für Fehlmeldungen ist hier gering.
Ausblick und Zusammenfassung
Der kürzlich verabschiedete Cyber Resilience Act und die neue EU-Maschinenverordnung fordern, dass die Sicherheit schon bei der Softwareentwicklung berücksichtigt wird (Security by Design). Die Softwareindustrie setzt zunehmend auf speichersichere Sprachen. Die Sprache Rust verhindert Speicherfehler beim Kompilieren durch strenge Sprachregeln. Der Compiler wird ständig weiterentwickelt und seine Analysen werden präziser [20], sodass es komfortabler wird mit Rust zu entwickeln. Wir empfehlen den Einsatz von zusätzlichen Werkzeugen [9-12,14] um auch den Unsafe Code zu prüfen und weitere Werkzeuge [15,18,19] um bekannte Schwachstellen in verwendeten Softwareabhängigkeiten zu erkennen. Das Fraunhofer IEM entwickelt in seiner Forschung das Tool Cargo Flowcheck, mit dem eine noch viel präzisere Erkennung von Schwachstellen in Softwareabhängigkeiten als bisher möglich werden soll. (sg)
Literaturverzeichnis
[1] MITRE CORPORATION: CWE Top 25 Most Dangerous Software Weaknesses. Unter: https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html, 11. Oktober 2024
[2] MICROSOFT: A proactive approach to more secure code, 2019
[4] MOZILLA: Implications of Rewriting a Browser Component in Rust. Unter: https://hacks.mozilla.org/2019/02/rewriting-a-browser-component-in-rust/, 11. Oktober 2024
[5] U. S. CYBERSECURITY AND INFRASTRUCTURE SECURITY AGENCY; U. S. NATIONAL SECURITY AGENCY; AUSTRALIAN CYBER SECURITY CENTRE; CANADIAN CENTRE FOR CYBER SECURITY; UNITED KINGDOM NATIONAL CYBER SECURITY CENTRE; NEW ZEALAND NATIONAL CYBER SECURITY CENTRE; COMPUTER EMERGENCY RESPONSE TEAM NEW ZEALAND: The Case for Memory Safe Roadmaps: Why Both C-Suite Executives and Technical Experts Need to Take Memory Safe Coding Seriously
[6] BUNDESAMT FÜR SICHERHEIT IN DER INFORMATIONSTECHNIK: Fehlerhaftes Update von Crowdstrike Falcon. Unter: https://www.bsi.bund.de/SharedDocs/Cybersicherheitswarnungen/DE/2024/2024-257485-10F1_csw.html, 11. Oktober 2024
[8] QIN, B.; CHEN, Y.; YU, Z.; SONG, L.; ZHANG, Y.: Understanding memory and thread safety practices and issues in real-world Rust programs. In: Donaldson, A. F. (Ed.): Proceedings of the 41st ACM SIGPLAN Conference on Programming Language Design and Implementation. PLDI '20: 41st ACM SIGPLAN International Conference on Programming Language Design and Implementation, 15 06 2020 20 06 2020, London UK, ACM Digital Library, Association for Computing Machinery, New York,NY,United States, 2020, pp. 763–779
[9] Miri: An interpreter for Rust's mid-level intermediate representation. Unter: https://github.com/rust-lang/miri, 11. Oktober 2024
[10] cargo-fuzz: Command line helpers for fuzzing. Unter: https://github.com/rust-fuzz/cargo-fuzz, 11. Oktober 2024
[11] LI, Z.: MirChecker: A Simple Static Analysis Tool for Rust. Unter: https://github.com/lizhuohua/rust-mir-checker, 11. Oktober 2024
Dieser Beitrag wurde mit freundlicher Genehmigung des Autors aus dem Tagungsband des ESE Kongress 2024 übernommen.
* Ingo Budde ist seit 2018 Softwareentwickler und wissenschaftlicher Mitarbeiter in der Abteilung Sichere IoT-Systeme im Forschungsbereich Softwaretechnik & IT-Sicherheit des Fraunhofer IEM. In dieser Zeit bearbeitete er verschiedene Projekte mit Industrie- und Forschungspartnern u.a. aus dem Maschinen- und Anlagenbau zu den Themenfeldern Security by Design, Software Engineering und statischer Programmanalyse. Die Programmiersprache Rust hat er mehrfach eingesetzt, um die Sicherheit und Performanz der Systeme zu erhöhen. In einer wissenschaftlichen Arbeit hat er sich mit dem Thema Sicherheit im Rust-Ökosystem auseinandergesetzt und verschiedene Werkzeuge zur Erhöhung der Sicherheit untersucht sowie eine Erweiterung für eines dieser Werkzeuge entwickelt.