{"id":20613,"date":"2021-08-19T03:55:28","date_gmt":"2021-08-19T01:55:28","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=20613"},"modified":"2023-06-18T18:00:06","modified_gmt":"2023-06-18T16:00:06","slug":"mechanismen-bei-system-programmiersprachen-zum-erreichen-von-memory-thread-und-type-safety","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/08\/19\/mechanismen-bei-system-programmiersprachen-zum-erreichen-von-memory-thread-und-type-safety\/","title":{"rendered":"Mechanismen bei System-Programmiersprachen zum Erreichen von Memory-, Thread- und Type-Safety"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Motivation<\/h2>\n\n\n\n<p>Ende letzten Monats (Juli, 2021) hat die CWE (Common Weakness Enumeration) einen Bericht ver\u00f6ffentlicht, welcher die Top 25 der Software-Schwachstellen aufzeigt. Es handelt sich dabei um eine Auswertung von gefundenen Schwachstellen der letzten zwei Jahre in verschiedenen Software-Systemen. Der Bericht umfasst eine Liste der 40 schwerwiegensten Schwachstellen. Dabei handelt es sich um Schwachstellen, welche einfach zu finden oder auszunutzen sind, h\u00e4ufig vorkommen und \u00e4u\u00dferst wirkungsvoll und dementsprechend gef\u00e4hrlich sind. [1]<\/p>\n\n\n\n<p>Platz 1 der Liste wird von einer Speicher-Schwachstelle belegt, dem Out-Of-Bounds-Write dicht gefolgt vom Out-Of-Bounds-Read auf Platz 3. Insgesamt sind 7 der 40 vorgestellten Schwachstellen solche, welche aufgrund mangelnder Speicher-Sicherheit entstehen k\u00f6nnen. Andere gef\u00e4hrliche Schwachstellen entstehen aus Fehlern in der parallelen Programmierung sowie durch zu schwache Typ-Systeme in der verwendeten Programmier-Sprache. [1]<\/p>\n\n\n\n<p>Speicher-spezifische Software-Schwachstellen sind die mit am h\u00e4ufigsten vorkommenden Schwachstellen. Circa 70% der Schwachstellen in Systemen von Microsoft sind auf Speicher-Fehler zur\u00fcck zu f\u00fchren. [11]<\/p>\n\n\n\n<p>Andere Beispiele f\u00fcr die H\u00e4ufigkeit von Speicher-Fehlern sind der Exim-Mail-Server vergangenen Mai, bei dem 12 der 21 gefundenen Schwachstellen Speicher-spezifische Fehler waren. [12] Aber auch zwei schwerwiegende Sicherheits-L\u00fccken beim Samba-LDAP-Server vom M\u00e4rz diesen Jahres sind auf Speicher-Fehler in der Software zur\u00fcck zu f\u00fchren. [13] In der Webkit-Komponente von Apple&#8217;s MacOS wurde ebenfalls ein Speicher-Fehler in Form eines Puffer-\u00dcberlaufs entdeckt. [14]<\/p>\n\n\n\n<!--nextpage-->\n\n\n\n<p>Code-Fehler im Programm f\u00fchren nicht nur zu sp\u00e4teren Sicherheits-L\u00fccken in der Anwendung, sondern erh\u00f6hen die Entwicklungs-Kosten, da ein gro\u00dfer Teil der Entwicklungs-Zeit f\u00fcr die Fehler-Behebung teils schwer zu findender Programm-Fehler investiert werden muss.<\/p>\n\n\n\n<p> Speicher-Fehler sowie Fehler in der parallelen Programmierung werden erm\u00f6glicht, wenn die verwendete Programmier-Sprache diesbez\u00fcglich zu schwache Restriktionen besitzt. In den weit verbreiteten alten System-Sprachen C und C++ wurde bewusst auf derartige Einschr\u00e4nkungen verzichtet, um eine m\u00f6glichst vollumf\u00e4ngliche Kontrolle \u00fcber die Anwendung und den verwendeten Speicher zu erhalten. Zudem soll damit auch die bestm\u00f6gliche Effizienz bez\u00fcglich dem Speicher-Verbrauch und der Laufzeit der Anwendung erm\u00f6glicht werden. Andere Programmier-Sprachen wie etwa Java besitzen eine gr\u00f6\u00dfere Sicherheit und vermeiden Speicher-Fehler zum gro\u00dfen Teil. Dadurch wird jedoch die Laufzeit beeintr\u00e4chtigt, aber vor allem der Speicher-Verbrauch durch Garbage-Collection stark erh\u00f6ht. Dies ist f\u00fcr den Gro\u00dfteil der heutigen Anwendungen au\u00dfreichend, vor allem, da die Hardware seit der Ver\u00f6ffentlichung von C schneller geworden ist und mehr Speicher zur Verf\u00fcgung stellt. F\u00fcr Performance-kritische Systeme wie beispielsweise Betriebssysteme, Firmware, Treiber oder eingebettete Systeme wird aber weiterhin C und C++ verwendet, da hier die komplette Kontrolle \u00fcber den Speicher sowie den Prozessor erm\u00f6glicht wird [38].<\/p>\n\n\n\n<p>Rust, eine weitere System-Sprache, welche seit 2010 existiert, versucht, die Schw\u00e4chen von C und C++ zu beseitigen und dennoch eine etwa gleichbleibende Performance zu C und C++ zu bieten. Dies ist jedoch im Kontrast zu der Annahme, dass Sicherheit, also zus\u00e4tzliche \u00dcberpr\u00fcfungen, nicht umsonst zu bekommen ist, also immer auch Nachteile wie etwa Performance-Reduzierung mit sich bringt.<\/p>\n\n\n\n<p>Daher ist das Ziel dieses Artikels, die Schwachstellen der Kategorien Memory-Safety, Thread-Safety sowie Type-Safety des Top 25-Artikels des CVE entsprechend zu analysieren. Es wird auf Nachteile aber auch die daraus resultierenden M\u00f6glichkeiten von C und C++ bez\u00fcglich der jeweiligen Schwachstelle eingegangen, aber auch ein L\u00f6sungs-Konzept in Rust f\u00fcr das entsprechende Problem beschrieben. Dabei wird unter anderem auf Performance und Speicher-Verbrauch geachtet, um herauszufinden, ob Rust die lang etablierten System-Sprachen in diesem Bereich in Zukunft ersetzen k\u00f6nnte.<\/p>\n\n\n\n<p>In folgender Tabelle ist eine \u00dcbersicht der f\u00fcr diesen Artikel relevanten Schwachstellen, sortiert nach den Sicherheits-Bereichen, gegeben. Die Schwachstellen &#8216;<strong>Out-Of-Bounds-Read<\/strong>&#8216; und <strong>&#8216;-Write&#8217;<\/strong> sowie  &#8216;<strong>Improper Restriction of Operations within the Bounds of a Memory Buffer<\/strong>&#8216; werden zusammen in einem Kapitel behandelt, da diese gr\u00f6\u00dftenteils thematisch \u00fcbereinstimmen.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table class=\"has-fixed-layout\"><thead><tr><th>Bereich<\/th><th>Platzierung<\/th><th>Schwachstelle<\/th><th>Name<\/th><\/tr><\/thead><tbody><tr><td>Memory-Safety<\/td><td>1<\/td><td>CWE-787<\/td><td>Out-of-Bounds Write<\/td><\/tr><tr><td>Memory-Safety <\/td><td>3<\/td><td>CWE-125<\/td><td>Out-of-bounds Read<\/td><\/tr><tr><td> Memory-Safety <\/td><td>17<\/td><td>CWE-119<\/td><td>Improper Restriction of Operations within the Bounds of a Memory Buffer<\/td><\/tr><tr><td> Memory-Safety <\/td><td>7<\/td><td>CWE-416<\/td><td>Use After Free (Dangling Pointer)<\/td><\/tr><tr><td> Memory-Safety <\/td><td>15<\/td><td>CWE-476<\/td><td>Null-Pointer Dereferenzierung<\/td><\/tr><tr><td> Memory-Safety <\/td><td>32<\/td><td>CWE-401<\/td><td>Missing Release of Memory after Effective Lifetime (Memory Leak)<\/td><\/tr><tr><td> Memory-Safety <\/td><td>12<\/td><td>CWE-190<\/td><td>Integer Overflow or Wraparound<\/td><\/tr><tr><td>Thread-Safety<\/td><td>33<\/td><td>CWE-362<\/td><td>Concurrent Execution using Shared Resource with Improper Synchronization (&#8216;Race Condition&#8217;)<\/td><\/tr><tr><td>Type-Safety<\/td><td>36<\/td><td>CWE-843<\/td><td>Access of Resource Using Incompatible Type (&#8216;Type Confusion&#8217;)<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 1: Gefundene Schwachstellen in CWE-Top-25 bez\u00fcglich Memory\/- Thread\/- und Type-Safety<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Rust<\/h2>\n\n\n\n<p>Im folgenden Kapitel wird zun\u00e4chst auf drei wichtige Konzepte in Rust eingegangen, auf welche in den darauffolgenden Kapiteln immer wieder Bezug genommen wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ownership-Modell<\/h3>\n\n\n\n<p>Um auf L\u00f6sungen seitens von Rust bez\u00fcglich der Schwachstellen Bezug zu nehmen, wird zun\u00e4chst ein wichtiges Konzept in Rust beschrieben. Dieses erm\u00f6glicht Memory-Safety ohne Garbage-Collection, was die Stabilit\u00e4t von Anwendungen mit gleichbleibender Performance bezogen auf C\/C++ erm\u00f6glicht. Dies wird durch eine Pr\u00fcfung zur Compile-Zeit erreicht.<\/p>\n\n\n\n<p>Das Konzept dient als Zugangs-Kontrolle, um zu \u00fcberpr\u00fcfen, dass Code nicht auf beliebige Daten, sondern nur auf f\u00fcr ihn erlaubte Daten Zugriff hat. Das Ownership-Prinzip besagt, dass immer nur eine Variable gleichzeitig, eine bestimmte Ressource besitzen kann. Andere Variablen k\u00f6nnen diese Ressource ausleihen, um ebenfalls Zugriff zu erhalten. Dieses Prinzip wird Borrowing genannt. Wird eine Ressource neu erzeugt, so besitzt die Variable, der die Ressource zugewiesen wird, zun\u00e4chst die Verantwortung dar\u00fcber. Der Besitzer einer Ressource kann gewechselt werden, indem die Ressource \u00fcber eine Move-Operation, \u00e4hnlich wie in C++, einer anderen Variable, per Parameter zugewiesen oder als R\u00fcckgabe-Wert dem Aufrufer \u00fcbergeben wird [19].<\/p>\n\n\n\n<p>Die Ressource ist an die verantwortliche Variable gebunden. Sollte die Variable zerst\u00f6rt werden, wird die Ressource automatisch mit zerst\u00f6rt beziehungsweise freigegeben. Zus\u00e4tzlich kann \u00fcber die besitzende Variable die Ressource ver\u00e4ndert werden [19].<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Borrowing (Referenzen)<\/h4>\n\n\n\n<p>Beim Borrowing wird eine Referenz auf die Ressource \u00fcbergeben, sodass eine andere Software-Komponente darauf zugreifen kann, ohne dass die Verantwortung \u00fcber die Ressource wechselt. Es wird dabei vom Compiler garantiert, dass die Referenz nicht \u00fcber die Lebenszeit der Ressource hinaus existiert. Sollten Referenz-Variablen l\u00e4nger existieren, wird ein Compiler-Fehler geworfen [19].<\/p>\n\n\n\n<p>Es gibt zwei Arten von Referenzen, welche jeweils eigene Restriktionen und M\u00f6glichkeiten bieten. Immutable, also nicht ver\u00e4nderbare Referenzen auf eine Ressource k\u00f6nnen beliebig oft im Programm existieren, da hier keine der Zugriffe, die Ressource ver\u00e4ndern darf. Damit ist gew\u00e4hrleistet, dass alle Software-Komponenten mit der selben stabilen Version der Ressource arbeiten k\u00f6nnen, ohne dass sie sich zwischendurch ver\u00e4ndert. Solange eine immutable-Referenz existiert, darf die Ressource nicht ge\u00e4ndert werden [19].<\/p>\n\n\n\n<p>Die andere Referenz-Art ist die ver\u00e4nderbare (mutable) Referenz. Existiert eine ver\u00e4nderbare Referenz, so darf es keine weitere mutable oder immutable Referenz geben. So wird garantiert, dass Software-Komponenten, welche eine unver\u00e4nderbare Referenz besitzen, davon aus gehen k\u00f6nnen, dass sich die Ressource w\u00e4hrend der Lebenszeit der Referenz nicht \u00e4ndert [19].<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Clone \/ Copy<\/h4>\n\n\n\n<p>Rust f\u00fchrt die Move-Operation bei Zuweisungen oder Parameter-\u00dcbergaben automatisch aus, anders als in C++, wo das explizit geschrieben werden muss. Um jedoch einen Wert in Rust zu kopieren, muss eine spezielle Kopier-Funktion (.clone()) auf der Ressource aufgerufen werden [40][21].<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Beispiele<\/h4>\n\n\n\n<p>Ein Beispiel, wie das Ownership-Modell m\u00f6gliche Speicher-Fehler verhindern kann, ist wie folgt gegeben.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn fct1() -&gt; Vec&lt;i32&gt;{&lt;br&gt;&nbsp;&nbsp;&nbsp;let mut vec = Vec::new();&lt;br&gt;   vec.push(0);&lt;br&gt;   vec \/\/ return with move&lt;br&gt;}&lt;br&gt;fc fct2(vec: &amp;Vec&lt;i32&gt;){&lt;br&gt;   \/\/ destroy reference&lt;br&gt;}&lt;br&gt;fc fct3(vec: Vec&lt;i32&gt;){&lt;br&gt;   \/\/ destroy vec&lt;br&gt;}&lt;br&gt;fc main(){&lt;br&gt;   let vec = fct1();&lt;br&gt;   fct2(&amp;vec); \/\/ pass reference&lt;br&gt;   fct3(vec); \/\/ pass with move&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 1: Beispiel-Code f\u00fcr Ownership-Konzept in Rust, abgeleitet von [19].<\/figcaption><\/figure>\n\n\n\n<p>Wenn die Main-Funktion ausgef\u00fchrt wird, wird zun\u00e4chst die &#8216;<strong>fct1<\/strong>&#8216;-Funktion aufgerufen. Diese erzeugt ein Array und bef\u00fcllt es mit einem Element. Damit ist die Variable &#8216;vec&#8217; zun\u00e4chst der Besitzer. Das Array wird am Schluss als R\u00fcckgabe-Wert zur\u00fcckgegeben. Da es sich um eine Move-Operation handelt, wird die Verantwortung \u00fcber das Array an die aufrufende Funktion \u00fcbergeben. In der Main-Funktion wird anschlie\u00dfend eine immutable Referenz an &#8216;<strong>fct2<\/strong>&#8216; \u00fcbergeben. Ist &#8216;<strong>fct2<\/strong>&#8216; fertig abgearbeitet, wird der Kontext aufger\u00e4umt und die Referenz auf die Ressource wieder zerst\u00f6rt. Am Schluss wird der dritten Funktion &#8216;<strong>fct3<\/strong>&#8216; das Array per Move-Operation als Parameter \u00fcbergeben, sodass nun der Besitzer der Ressource zu &#8216;<strong>fct3<\/strong>&#8216; wechselt. Kehrt &#8216;<strong>fct3<\/strong>&#8216; nun wieder zum Aufrufer zur\u00fcck, so wird das Array automatisch zerst\u00f6rt und beanspruchter Speicher wieder frei gegeben. Der Entwickler muss sich nun keine Gedanken mehr dar\u00fcber machen, welche Software-Komponente nun f\u00fcr das Freigeben von Speicher zust\u00e4ndig ist, oder ob noch Referenzen auf die Ressource existieren. All diese Pr\u00fcfungen werden zur Compilezeit durchgef\u00fchrt, sodass die Performance kaum betroffen ist. [19]<\/p>\n\n\n\n<p>Folgendes Beispiel soll die Bedeutung von &#8216;<strong>clone()<\/strong>&#8216;, also das Kopieren einer Ressource, verdeutlichen.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code class=\"\" data-line=\"\">let v1 = vec![1,2,3];&lt;br&gt;let v2 = v1.clone(); \/\/ copy&lt;br&gt;let v3 = v1; \/\/ move&lt;br&gt;let v4 = v1; \/\/ compiler error<\/code><\/td><\/tr><\/tbody><\/table><figcaption>Code 2: Beispiel f\u00fcr die Verwendung von &#8216;clone()&#8217; in Rust. Abgeleitet von [21].<\/figcaption><\/figure>\n\n\n\n<p>Zun\u00e4chst wird wieder ein Array erzeugt welches anschlie\u00dfend \u00fcber &#8216;<strong>clone()<\/strong>&#8216; kopiert wird. Dabei verbleibt die Verantwortung \u00fcber die alte Ressource bei &#8216;<strong>v1<\/strong>&#8216; und &#8216;<strong>v2<\/strong>&#8216; wird der Besitzer der neu erstellten Ressource. Danach wird jedoch die Verantwortung der zuerst erstellten Ressource per Move-Operation an &#8216;<strong>v3<\/strong>&#8216; \u00fcbergeben, wodurch &#8216;<strong>v1<\/strong>&#8216; invalide wird. Da &#8216;<strong>v1<\/strong>&#8216; invalide ist, gibt es auch keine Verantwortung mehr, welche der Variablen &#8216;<strong>v4<\/strong>&#8216; \u00fcbergeben werden k\u00f6nnte. Daher erzeugt der Rust-Compiler hier einen Fehler.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rust-Pointer<\/h3>\n\n\n\n<p>Pointer, wie sie in C oder C++ existieren, sind in Rust nur unter Einschr\u00e4nkungen nutzbar. Dies muss zus\u00e4tzlich dem Rust-Compiler explizit mitgeteilt werden, indem der unsichere Modus von Rust genutzt wird, was im folgenden Abschnitt n\u00e4her erl\u00e4utert wird.<\/p>\n\n\n\n<p>F\u00fcr gew\u00f6hnlich werden aber Rust-Pointer wie <strong>Box&lt;T&gt;<\/strong> verwendet, um eine Adresse auf eine Ressource zu verwalten. Hierbei dient <strong>Box&lt;T&gt;<\/strong> als Wrapper-Objekt f\u00fcr die darunter liegende Speicher-Adresse. Wird der Pointer durch das Verlassen des Kontext zerst\u00f6rt, so wird die Ressource, auf die der Pointer zeigt, automatisch frei gegeben [25].<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Safe-Rust und Unsafe-Rust<\/h3>\n\n\n\n<p>Rust besitzt einen sehr konservativen Compiler. Dies bedeutet, dass er auch funktionierenden Code nicht kompiliert, wenn dieser in einer anderen Anwendungs-Umgebung Fehler verursachen w\u00fcrde. Zus\u00e4tzlich ist der Entwickler an das Schreiben sicheren Codes gebunden, was bei Low-Level-Programmierung teilweise nicht m\u00f6glich ist, wenn mit der Hardware oder dem Betriebssystem kommuniziert werden soll, oder eigene Bibliothekserweiterungen geschrieben werden sollen [39].<\/p>\n\n\n\n<p>Hierf\u00fcr bietet Rust eine M\u00f6glichkeit, unter gewissen Einschr\u00e4nkungen auch ausgew\u00e4hlte unsichere Aktionen wie C-\u00e4hnliche Pointer zu verwenden, um zum Beispiel mit C oder dem dem Betriebssystem zu kommunizieren. Diese M\u00f6glichkeit hei\u00dft Unsafe-Rust und muss bei Nutzung dem Rust-Compiler explizit mitgeteilt werden [39].<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Memory-Safety<\/h2>\n\n\n\n<p>Memory-Safety ist die Eigenschaft einer Programmiersprache oder Anwendung, keine Sicherheits-Schwachstellen oder andere Programm-Fehler in Bezug auf Speicher-Zugriffe zu erm\u00f6glichen. [15]<\/p>\n\n\n\n<p>C und C++ sind in diesem Fall klar Memory-Unsafe, da die Sprachen Pointer intern als ganz normale Integer behandeln. Dies bedeutet, dass als Speicher-Adresse ein beliebiger Wert angegeben werden kann, auf welchen versucht werden k\u00f6nnte, zuzugreifen. Zus\u00e4tzlich kann durch Pointer-Arithmetik beliebig mit den Adressen gerechnet werden. Das Objekt-Layout von Strukturen kann Byte f\u00fcr Byte gelesen und beschrieben werden, was beliebige M\u00f6glichkeiten der Programmierung mit sich bring, jedoch auch viel Platz f\u00fcr Speicher-Fehler bietet.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-787\/125: Out-Of-Bounds-Read \/ -Write |  CWE-119  Improper Restriction of Operations within the Bounds of a Memory Buffer<\/h3>\n\n\n\n<p>Eine auch als Buffer-Overflow oder Buffer-Overrun bzw. Buffer-Underflow bezeichnete Schwachstelle, bei der es m\u00f6glich ist, Speicher-Zugriffe au\u00dferhalb des im Kontext vorgesehenen Speicher-Bereichs zu t\u00e4tigen [1][2][3][7]. In Tabelle 2 ist ein Beispiel gegeben.<\/p>\n\n\n\n<p>Die Variable &#8216;<strong>arr<\/strong>&#8216; ist dabei wie folgt definiert: <strong>int arr[7];<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Typ<\/th><th>Array-Syntax (C\/C++)<\/th><th>Pointer-Syntax (C\/C++)<\/th><th>Assembly (MASM)<\/th><\/tr><\/thead><tbody><tr><td>Out-Of-Bounds-Read<\/td><td><pre><code class=\"\" data-line=\"\">int i = arr[-1];<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">int i = *(arr+(-1));<\/code><\/pre><br><\/td><td><pre><code class=\"\" data-line=\"\">mov r8d,dword ptr [arr-4]&lt;br&gt;mov dword ptr [i],r8d<\/code><\/pre><\/td><\/tr><tr><td>Out-Of-Bounds-Write<\/td><td><pre><code class=\"\" data-line=\"\">arr[7] = i;<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">*(arr+7) = i;<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">mov r8d,dword ptr [i]&lt;br&gt;mov dword ptr [arr+28],r8d<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 2: Out-Of-Bounds-Zugriffe in C \/ C++ in verschiedener Darstellung sowie das m\u00f6gliche generierte Assembly<\/figcaption><\/figure>\n\n\n\n<p>In obigem Beispiel ist gut ersichtlich, dass C\/C++ bei Array-Operationen Pointer-Arithmetik zum Berechnen der Speicher-Adresse verwendet. Damit existiert keine \u00dcberpr\u00fcfung des Index zur Laufzeit. Da Adressen auch subtrahiert werden k\u00f6nnen, ist daher ein negativer Index in C\/C++ erlaubt.<\/p>\n\n\n\n<p>Verhindert werden kann der Speicher-Fehler durch &#8216;<strong>Bounds-Checking<\/strong>&#8216;, also dass \u00dcberpr\u00fcfen des Index bzw. der Position, an der im Speicher zugegriffen werden soll. Liegt die Position in einem validen Speicher-Bereich, kann im Programm-Code weiter fortgefahren werden, ansonsten sollte die Anwendung angehalten werden, um dem Entwickler die M\u00f6glichkeit zu geben, den Fehler schnellstm\u00f6glich zu finden, sowie weiteren Schaden f\u00fcr die Anwendung zu vermeiden [2][3][7].<\/p>\n\n\n\n<p>Ein m\u00f6glicher &#8216;<strong>Bounds-Check<\/strong>&#8216; k\u00f6nnte dabei wie folgt aussehen:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">bool boundsCheck = idx &gt;= arr.size();&lt;br&gt;if (boundsCheck){&lt;br&gt;   throw new OutOfBoundsException();&lt;br&gt;}&lt;br&gt;T v = arr[idx];<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 3: M\u00f6gliche Out-Of-Bounds-L\u00f6sung mittels Bounds-Check.<\/figcaption><\/figure>\n\n\n\n<p>Dies kann teilweise zur Compilezeit geschehen, wenn die gr\u00f6\u00dfe des Arrays bereits bekannt ist, teilweise aber auch erst zur Laufzeit durchgef\u00fchrt werden, wenn Speicher  dynamisch  zur Laufzeit allokiert wird. Um die Performance nicht allzu stark zu beeintr\u00e4chtigen, werden in der STL (Standard Template Library) von C++ oft zwei Varianten einer Funktion angeboten, eine mit und eine ohne &#8216;<strong>Bounds-Checking<\/strong>&#8216;. Damit braucht nur dann getestet werden, wenn die Eingaben nicht vorher bestimmbar sind, wie die eines Benutzers. Ein Beispiel f\u00fcr verschiedene Funktions-Versionen sind hierbei &#8216;std::vector::at()&#8217; f\u00fcr die sichere, sowie &#8216;std::vector::operator[]()&#8217; f\u00fcr die unsichere Variante eines Array-Zugriffs [26]. Dies k\u00f6nnte aber weiterhin durch ein Makro erg\u00e4nzt werden, welches eine Typpr\u00fcfung ausschlie\u00dflich im Debug-Modus der Anwendung durchf\u00fchrt und im Release-Modus die \u00dcberpr\u00fcfung wegl\u00e4sst. Bei externen Eingaben muss aber nachwievor eine Eingabe-Validierung stattfinden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<p>Rust bietet im sicheren Modus mit Pointer-Wrappern wie &#8216;<strong>Box&lt;T&gt;<\/strong>&#8216; keine M\u00f6glichkeit f\u00fcr Pointer-Arithmetik. <strong>Box&lt;T&gt;<\/strong> verh\u00e4lt sich im Grunde \u00e4hnlich wie eine Referenz-Variable in Java, da die Speicher-Adresse fix ist [25]. Datenstrukturen wie der Vector der Standard-Bibliothek von Rust, welche Low-Level-Speicher-Verwaltung betreiben, f\u00fchren <strong>Bounds-Checking<\/strong> zur Laufzeit aus. Eine zweite Variante ohne <strong>Bounds-Checking<\/strong> existiert nicht, weil dies nicht sicher w\u00e4re [27].<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-416: Use After Free (Dangling Pointer)<\/h3>\n\n\n\n<p>Bei &#8216;<strong>Use-After-Free<\/strong>&#8216; handelt es sich um einen Speicher-Fehler, bei welchem versucht wird, auf einen bereits freigegebenen Speicher-Bereich zuzugreifen [4]. Dies kann sowohl auf dem Stack, als auch auf dem Heap passieren, wie folgendes Beispiel zeigt:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Speicher-Art<\/th><th>Code (C\/C++)<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td>Stack<\/td><td><pre><code class=\"\" data-line=\"\">int* fct(){&lt;br&gt;   int i = 4;&lt;br&gt;   return &amp;i;&lt;br&gt;}<\/code><\/pre><\/td><td>R\u00fcckgabe eines Pointers, welcher auf Stack-Speicher zeigt. Speicher wird automatisch bei Beendigung der Funktion frei gegeben.<\/td><\/tr><tr><td>Heap<\/td><td><pre><code class=\"\" data-line=\"\">char *pBuffer = (char*)malloc(32);&lt;br&gt;free(pBuffer);&lt;br&gt;char i = pBuffer[4]; \/\/ read invalid data&lt;br&gt;pBuffer[8] = i; \/\/ write to invalid data<\/code><\/pre><\/td><td>Manuelle Speicher-Verwaltung: Anfrage und Freigabe des Speichers liegt in der Verantwortung des Programmierers.<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 3: Beispiele f\u00fcr &#8216;Use-After-Free&#8217; f\u00fcr Stack\/- und Heap-Speicher<\/figcaption><\/figure>\n\n\n\n<p>Vor allem in der manuellen Speicher-Verwaltung bez\u00fcglich dem Heap ist der Hauptgrund f\u00fcr diese Schwachstelle, dass es keine klare Rollenverteilung beziehungsweise Zust\u00e4ndigkeit gibt, die durch den Compiler gepr\u00fcft werden kann. Daher ist es die Aufgabe des Entwicklers, welche Komponenten f\u00fcr welchen Speicher-Bereich verantwortlich sind, diesen also freigeben d\u00fcrfen, was zu Speicher-Fehlern f\u00fchren kann.<\/p>\n\n\n\n<p>Die Folgen belaufen sich bestenfalls auf einen Absturz der Anwendung durch eine Zugriffs-Verweigerung (Access-Violation) hin. Anderenfalls k\u00f6nnen sensible Daten wie Zugangs-Codes ausgelesen oder geschrieben werden, wenn sich die Daten an dieser Stelle noch im Speicher befinden, sowie Fremd-Code angesprungen und ausgef\u00fchrt werden. Das Manipulieren bereits freigegebener Speicher-Bereiche kann beliebige andere Software-Komponenten beeinflussen und f\u00fchrt daher zu undefiniertem Verhalten der Anwendung und daher auch teilweise zu Fehlern, welche nur schwer reproduzierbar sind [4].<\/p>\n\n\n\n<p>Die einfachste L\u00f6sung f\u00fcr dieses Problem w\u00e4re, den Pointer nach der Freigabe auf Null zu setzen, um per Pr\u00fcfung zu erkennen, ob ein Pointer noch auf validen Speicher zeigt. Sollte ein Null-Pointer dereferenziert werden, wird eine Null-Pointer-Exception geworfen und die Anwendung beendet, was zu einer schnellen Erkennung des Fehler f\u00fchrt [4]. Diese L\u00f6sung liegt jedoch wieder in der Verantwortung des Entwicklers und kann daher vergessen werden. Desweiteren handelt es sich hier um eine weitere Zuweisung (p = nullptr;), welche evtl. auf manchen Systemen zu einer schlechteren Performance f\u00fchren k\u00f6nnte.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>C++<\/th><th>Rust<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">vector&lt;string&gt; v;&lt;br&gt;v.push_back(&quot;hello&quot;);&lt;br&gt;auto &amp;str = v[0];&lt;br&gt;v.push_back(&quot;world&quot;);&lt;br&gt;cout &lt;&lt; str.c_str() &lt;&lt; endl;<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">let mut v = vec![];&lt;br&gt;v.push(&quot;hello&quot;);&lt;br&gt;let str = &amp;v[0];&lt;br&gt;v.push(&quot;world&quot;);&lt;br&gt;println!(&quot;{}&quot;,str);<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 4: Beispiel: Vermeidung von m\u00f6glichen Speicher-Fehlern in Rust im Gegensatz zu C++. Von [21] abgeleitet.<\/figcaption><\/figure>\n\n\n\n<p>In obigem Beispiel wird der Variablen &#8216;str&#8217; eine Referenz auf das erste Feld im Array zugewiesen. Dar\u00fcber wird am Schluss versucht, auf das erste Feld zuzugreifen, nachdem das Array ver\u00e4ndert wurde. Hierbei kann es passieren, dass die Referenz ung\u00fcltig wird und auf einen invaliden Speicher-Bereich zeigt. Dies ist dann der Fall, wenn im Array nicht gen\u00fcgent Speicher reserviert ist, um das nueue Element &#8216;world&#8217; einzuf\u00fcgen. Dadurch muss ein neuer Speicher-Bereich allokiert werden, in welchen die alten Elemente und das Neue hinein kopiert werden. Der alte Speicher-Bereich wird anschlie\u00dfend frei gegeben. Die Referenz zeigt aber noch auf den frei gegebenen Speicher-Bereich. Wird die Referenz nun verwendet, besitzt diese Anwendung eine Use-After-Free-Schwachstelle mit den entsprechenden m\u00f6glichen Folgen. [21]<\/p>\n\n\n\n<p>Rust kann durch das Ownership-Modell unter anderem Use-After-Free-Schwachstellen vermeiden, wie der Rust-Code im obigen Beispiel zeigt. Die Referenz &#8216;<strong>str<\/strong>&#8216; ist immutable. Wird die Ressource vom Inhaber der Ressource ver\u00e4ndert, darf auf die immutable Referenz nicht mehr zugegriffen werden. Dies wird zur Compilezeit gew\u00e4hrleistet. Dadurch verursacht obiger Code von Rust einen Compiler-Fehler, sodass ein m\u00f6glicher Speicher-Fehler von vornherein verhindert werden kann. Anzumerken ist noch, dass dieser Code in Rust generell nicht erlaubt ist, auch wenn der Entwickler garantieren kann, dass in dieser Situation gen\u00fcgend Speicher im Array vorhanden ist. Dadurch muss der Code an manchen Stellen evtl. umst\u00e4ndlicher geschrieben werden, verhindert aber Speicher-Fehler, ohne gro\u00dfartigen Performance-Verlust. [21]<\/p>\n\n\n\n<p>Generell k\u00f6nnen die sicheren Rust-Pointer nicht auf invalide Speicher-Bereiche zeigen. Dar\u00fcber hinaus entspricht &#8216;<strong>Box&lt;T&gt;<\/strong>&#8216; einem Pointer, welcher ausschlie\u00dflich auf Speicher im Heap zeigt. Daher sind im abgesicherten Modus von Rust, Pointer auf lokale Variablen nicht m\u00f6glich [25]. Eine m\u00f6gliche L\u00f6sung f\u00fcr Use-After-Free auf dem Stack ist daher wie folgt gegeben.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn fct() -&gt; Box&lt;i32&gt; {&lt;br&gt;   let x: i32 = 4;&lt;br&gt;   Box&lt;i32&gt;::new(x)&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 4: Beispiel-L\u00f6sung f\u00fcr Use-After-Free bei Stack-Werten in Rust.<\/figcaption><\/figure>\n\n\n\n<p>In obigem Beispiel wird im Heap speicher allokiert und mit dem Wert 4 der Variablen &#8216;x&#8217; beschrieben. Anschlie\u00dfend wird der Pointer per Move-Operation der aufrufenden Routine \u00fcbergeben.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-476: Null-Pointer Dereferenzierung<\/h3>\n\n\n\n<p>Hierbei handelt es sich um das Dereferenzieren eines Null-Pointers, was zum Absturz der Anwendung f\u00fchrt. Sollte der Prozess jedoch Rechte besitzen, auf die Speicher-Adresse 0 zuzugreifen, k\u00f6nnte auch hier externe Code-Ausf\u00fchrung m\u00f6glich sein. [6] Die Schwachstelle wird durch fehlende Abfragen beziehungsweise \u00dcberpr\u00fcfungen auf Null hervorgerufen, zum Beispiel, wenn Funktionen Null als R\u00fcckgabewert f\u00fcr einen Fehler zur\u00fcck geben. Null-Pointer-Dereferenzierung k\u00f6nnte aber auch durch konkurierende Threads entstehen. [6] Folgendes Beispiel, veranschaulicht die Schwachstelle:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Code (C\/C++)<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">void fct(char *pIp){&lt;br&gt;   char pHostName[64];&lt;br&gt;   Obj *pHost = getHostByAddr(pIp);&lt;br&gt;   strcpy(pHostName,pHost-&gt;m_name);&lt;br&gt;   \/\/ ...&lt;br&gt;}<\/code><\/pre><\/td><td>Sollte die Adresse keinem Host zugeordnet werden k\u00f6nnen, wird ein Null-Pointer bei &#8216;getHostAddr()&#8217; zur\u00fcck gegeben, was zu einer Null-Pointer-Dereferenzierung bei &#8216;pHost-&gt;m_name&#8217; f\u00fchrt.<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 5: Beispiel einer Null-Pointer-Dereferenzierung, abgeleitet von [6]<\/figcaption><\/figure>\n\n\n\n<p>Als L\u00f6sung in C\/C++ sollte der Pointer vor der Verwendung auf Null gepr\u00fcft werden und ggf. bei mehreren Threads der Zugriff zus\u00e4tzlich gelockt werden. Der Compiler kann den Programmierer hierbei auch verpflichten, uninitialisierte Pointer vor der ersten Verwendung zu initialisieren, jedoch nur wenn diese im selben Kontext definiert sind. [6]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<p>Die sicheren Pointer von Rust wie &#8216;Box&lt;T&gt;&#8217; k\u00f6nnen keinen Null-Wert besitzen. Eine Null-Pointer-Dereferenzierung ist dadurch ausgeschlossen. In Rust ist gew\u00e4hrleistet, das sichere Pointer auf einen validen Speicher-Bereich zeigen [25]. Ein Beispiel f\u00fcr Null-\u00e4hnliche Verarbeitung ist in der Rust-L\u00f6sung im nachsten Abschnitt gegeben.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-401: Missing Release of Memory after Effective Lifetime<\/h3>\n\n\n\n<p>Als Memory-Leak wird eine Schwachstelle bezeichnet, bei welcher eine Anwendung Speicher belegt, welcher f\u00fcr sie aber nicht erreichbar ist, da kein Pointer darauf zeigt. Dies kann bei der manuellen Speicherverwaltung im Heap passieren, wenn es vers\u00e4umt wurde den nicht mehr ben\u00f6tigten Speicher frei zu geben. Auch hier kann die unklare Zust\u00e4ndigkeit der Software-Komponenten f\u00fcr die jeweiligen Speicher-Bereiche eine Rolle spielen.[8] Folgendes Beispiel soll die Schwachstelle veranschaulichen:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Code (C\/C++)<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">char* fct(){&lt;br&gt;   char *pBuffer = (char*)malloc(size);&lt;br&gt;   if (!bCond){&lt;br&gt;      return nullptr;&lt;br&gt;   }&lt;br&gt;   return pBuffer;&lt;br&gt;}<\/code><\/pre><\/td><td>Sollte eine Bedingung &#8216;bCond&#8217; fehlschlagen, wird direkt zur\u00fcck gekehrt, ohne den Speicher davor wieder frei zu geben.<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 6: Beispiel-Code f\u00fcr Memory-Leak abgeleitet von [8].<\/figcaption><\/figure>\n\n\n\n<p>Die Folgen dieser Schwachstelle sind das Verbrauchen von immer mehr Speicher. Dies f\u00fchrt irgendwann dazu, dass immer \u00f6ffters Speicher-Bereiche auf die Festplatte zur\u00fcck und neueSpeicher-Bereiche wieder herein geladen werden m\u00fcssen (Trashing). Hierbei erh\u00f6hen sich die Zugriffszeiten auf den Speicher, wobei die Anwendung auch einfrieren kann. Sollte nicht mehr gen\u00fcgen Speicher f\u00fcr die Anwendung verf\u00fcgbar sein, wird diese in der Regel vom Betriebssystem automatisch beendet. [8]<\/p>\n\n\n\n<p>Das Verwenden einer automatischen Speicher-Verwaltung wie etwa Garbage-Collection ist eine m\u00f6gliche L\u00f6sung f\u00fcr das Problem. [8] Der gro\u00dfe Zusatz-Speicher, der dabei aber ben\u00f6tigt wird, ist f\u00fcr die System-Programmierung f\u00fcr SPeicher-sensible Anwendungen keine Option. Daher werden nur einzelne Bestandteile der automatischen Speicher-Verwaltung in C\/C++ verwendet, wie etwa dem Reference-Counting. [8]<\/p>\n\n\n\n<p>Beim Reference-Counting werden die Referenzen auf Speicher-Bereiche gez\u00e4hlt, um zu erkennen, wann ein Speicher-Bereich nicht mehr referenziert wird und daher wieder frei gegeben werden kann. Dies wird normalerweise mit Objekten erreicht, welche sich nach au\u00dfen hin wie ein normaler Pointer verhalten, jedoch intern den Z\u00e4hler des referenzierten Objektes inkrementieren, wenn die Referenz zugewiesen wurde, und wieder dekrementieren, wenn die Referenz verloren geht. Dies erh\u00f6ht zwar auch den Speicher-Verbrauch und die Laufzeit, aber deutlich geringer, als bei der vollst\u00e4ndigen Garbage-Collection. Beispiele hierf\u00fcr sind die Smart-Pointer in C++ wie &#8216;std::shared_ptr&#8217;, und &#8216;std::unique_ptr&#8217;.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<p>Aber auch Rust besitzt als m\u00f6gliche Technik, &#8216;Reference-Counting&#8217; mittels Objekten wie &#8216;<strong>Rc&lt;T&gt;<\/strong>&#8216; [22]. Sollte aber klar sein, dass einer Ressource immer nur eine verantwortliche Variable zugeteilt sein muss, kann auch ein einzelner Pointer wie &#8216;<strong>Box&lt;T&gt;<\/strong>&#8216; verwendet werden, um Memory-Leaks zu verhindern. Rust kennt f\u00fcr sicheren Programmcode keine Null-Pointer. Um ein \u00e4hnliches Verhalten wie in C\/C++ zu erhalten, muss &#8216;<strong>Option&lt;T&gt;<\/strong>&#8216; verwendet werden. &#8216;<strong>Option&lt;T&gt;<\/strong>&#8216; ist ein Datentyp, welcher einen Wert von None, oder einen Wert von Some(x) annehmen kann. &#8216;x&#8217; muss hierbei vom Typ T sein. Der Wert kann \u00fcber eine Switch-Kontrollstruktur abgefragt werden [24]. Folgendes Beispiel gibt eine L\u00f6sung f\u00fcr obigen C\/C++-Code in Rust mittels eines <strong>Box&lt;T&gt;<\/strong>-Objekts sowie dem &#8216;<strong>Option&lt;T&gt;<\/strong>&#8216;-Wert.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn fct() -&gt; Option&lt;Box&lt;i8&gt;&gt; {&lt;br&gt;   let x: Box&lt;i8&gt; = Box::new(5);&lt;br&gt;   if !bCond {&lt;br&gt;      None&lt;br&gt;   }&lt;br&gt;   Some(x)&lt;br&gt;}&lt;br&gt;fn main(){&lt;br&gt;   let x = fct();&lt;br&gt;   match x {&lt;br&gt;      None =&gt; \/*handle nullptr*\/,&lt;br&gt;      Some(x) =&gt; \/*handle valid value x*\/,&lt;br&gt;   }&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 5: Beispiel-L\u00f6sung in Rust f\u00fcr obige Memory-Leak-Schwachstelle<\/figcaption><\/figure>\n\n\n\n<p>In obigem Rust-Code wird die Funktion &#8216;<strong>fct<\/strong>&#8216; aufgerufen. Sollte in der Funktion &#8216;<strong>fct<\/strong>&#8216; der Wert &#8216;<strong>None<\/strong>&#8216; zur\u00fcckgegeben werden, wird durch das Ownership-Prinzip von Rust, der Pointer &#8216;<strong>Box&lt;i8&gt;<\/strong>&#8216; automatisch zerst\u00f6rt, wodurch der Speicher-Bereich, auf den der Pointer zeigt, frei gegeben wird. Sollte jedoch &#8216;<strong>Some(x)<\/strong>&#8216; zur\u00fcck gegeben werden, wird die Verantwortung \u00fcber den &#8216;<strong>Box&lt;i8&gt;<\/strong>&#8216;-Wert an die aufrufende Funktion &#8216;<strong>main<\/strong>&#8216; \u00fcbergeben. Der R\u00fcckgabe-Wert kann dann \u00fcber &#8216;<strong>match<\/strong>&#8216;, was in etwa einem &#8216;switch&#8217; in C\/C++ entspricht, abgefragt werden. Bei &#8216;<strong>Some(x)<\/strong>&#8216; kann \u00fcber &#8216;<strong>x<\/strong>&#8216; auf den &#8216;<strong>Box&lt;i8&gt;<\/strong>&#8216;-Wert zugegriffen werden.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Optimierung: Null Pointer Optimization<\/h4>\n\n\n\n<p>Bei bestimmten Datentypen wie zum Beispiel &#8216;<strong>Box&lt;T&gt;<\/strong>&#8216; kann Rust eine Optimierung bez\u00fcglich der Speicher-Gr\u00f6\u00dfe des &#8216;<strong>Option&lt;T&gt;<\/strong>&#8216;-Wertes durchf\u00fchren. Hierbei wird garantiert, dass die Gr\u00f6\u00dfe von &#8216;<strong>Option&lt;T&gt;<\/strong>&#8216; dem enthaltenen Datentyp &#8216;T&#8217; entspricht. Damit gibt es bez\u00fcglich der Gr\u00f6\u00dfe keinen Overhead [24].<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-190: Integer Overflow or Wraparound<\/h3>\n\n\n\n<p>Beim Integer-\u00dcberlauf handelt es sich um einen normalen Zahlen-\u00dcberlauf aufgrund begrenzter Speicher-Kapazit\u00e4ten im Registern der CPU. Er entsteht, wenn der Ergebnisdatentyp zu klein f\u00fcr das Ergebnis der Berechnung oder einer Zuweisung ist und das Ergebnis somit abgeschnitten werden muss, um noch in den Speicher zu passen [28][5]. Der Integer-\u00dcberlauf ist in C\/C++ besonders gef\u00e4hrlich, da im Standard die genaue Gr\u00f6\u00dfe von Daten-Typen nicht festgelegt ist, also je nach eingesetztem Compiler unterschiedlich sein kann. [29] M\u00f6gliche Folgen k\u00f6nnen Out-Of-Bounds-Zugriffe sowie Endlosschleifen, aber auch unerwartetes System-Verhalten sein, bis hin zum Absturz der Anwendung [5]. Folgendes Beispiel soll das unbeabsichtigte Verf\u00e4lschen von Werten durch Code visualisieren:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Code (C\/C++)<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">void fct(unsigned short val);&lt;br&gt;void fct2(){&lt;br&gt;   unsigned int currAmount, transferAmount;&lt;br&gt;   \/\/ ...&lt;br&gt;   unsigned int newAmount = currAmount + transferAmount;&lt;br&gt;   fct(newAmount);&lt;br&gt;}<\/code><\/pre><\/td><td>Wenn die Summe &#8216;currAmount&#8217; gr\u00f6\u00dfer als der f\u00fcr &#8216;unsigned int&#8217; m\u00f6gliche maximale Wert ist, entsteht ein falsches Ergebnis.<br>Sollte &#8216;currAmount&#8217; gr\u00f6\u00dfer als f\u00fcr &#8216;unsigned short&#8217; m\u00f6glich sein, wird das Ergebnis bei der Parameter-\u00dcbergabe teilweise abgeschnitten.<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 7: Beispiel f\u00fcr Zahlen-\u00dcberlauf inspiriert von [5]<\/figcaption><\/figure>\n\n\n\n<p>Das auch solche Fehler zu schwerwiegenden Katastrophen f\u00fchren k\u00f6nnen, zeigt das Ungl\u00fcck der Ariane V88-Rakete, welche im Jahr 1996 kurz nach dem Start durch einen arithmetischen \u00dcberlauf in einem Steuermodul die Flugbahn verlie\u00df und zerst\u00f6rt werden musste. [16]<\/p>\n\n\n\n<p>Zus\u00e4tzlich k\u00f6nnen Folge-Schwachstellen, wie etwa Out-Of-Bounds durch oben genannte Gegenma\u00dfnahmen entdeckt und somit R\u00fcckschl\u00fcsse auf die eigentliche Ursache, den Integer-Overflow, gezogen werden.<\/p>\n\n\n\n<p>Microsoft bietet f\u00fcr C++ die SafeInt-Bibliothek an, mit welcher Ganzzahl-\u00dcberl\u00e4ufe bei arithmetischen Operationen oder Castings erkannt werden k\u00f6nnen. Hierbei k\u00f6nnen einzelne Funktionen, aber auch Objekte verwendet werden, welche die primitiven Datentypen kapseln. [17][5]<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<p>Rust verh\u00e4lt sich hier je nach Compiler-Einstellung anders. Wird das Projekt als Debug-Version erstellt, werden f\u00fcr die primitiven Datentypen zus\u00e4tzliche Pr\u00fcfungen bei arithmetischen Operationen eingebaut. Tritt ein arithmetischer \u00dcberlauf auf, so wird dies erkannt und die Anwendung mit einem Fehler beendet. Im Release-Modus werden keine zus\u00e4tzlichen Pr\u00fcfungen eingebaut, sodass Zahlen-\u00dcberl\u00e4ufe zur Laufzeit unbemerkt bleiben k\u00f6nnen, aber eine bessere Performance erzielt wird [23].<\/p>\n\n\n\n<p>Sollten dennoch arithmetische Operationen auf Zahlen-\u00dcberl\u00e4ufe gepr\u00fcft werden, so existieren wie bei der SafeInt-Bibliothek auch, diverse Funktionen wie zum Beispiel &#8216;overflowing_add&#8217;, um f\u00fcr einzelne Berechnungen eine Pr\u00fcfung auf Integer-Overflows zu erm\u00f6glichen. Hierbei wird ein zus\u00e4tzlicher boolscher Wert zur\u00fcc gegeben, welcher angibt, ob es einen Overflow gab [23].<\/p>\n\n\n\n<p>Rust ist daher sehr \u00e4hnlich zu den herk\u00f6mmlichen Sprachen und ignoriert standardm\u00e4\u00dfig das \u00dcberlaufen von Zahlen-Werten zur Laufzeit im Release-Modus.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Thread-Safety<\/h2>\n\n\n\n<p>Eine Programm-Komponente oder ein Programm werden als Thread-Safe bezeichnet, wenn diese von mehreren Threads parallel ausgef\u00fchrt werden k\u00f6nnen, ohne das erwartete Laufzeit-Verhalten der Anwendung zu ver\u00e4ndern, also keine Race-Condition besitzen. Unter anderem soll die Anwendung auch keine Deadlocks enthalten, was teilweise durch Callback-Funktionen aber nicht ganz auszuschlie\u00dfen ist. [18]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (&#8216;Race Condition&#8217;)<\/h3>\n\n\n\n<p>Hierbei handelt es sich um die typische Race-Condition. Eine Race-Condition liegt vor, wenn mehrere Threads einen nicht synchronisierten geteilten Speicher-Bereich beschreiben wollen. Dies f\u00fchrt zu unerwartetem und vor allem undefiniertem Verhalten, dessen Fehlerquelle teilweise sehr schwer zu finden ist, da der Fehler schlecht reproduzierbar ist. Weitere Folgen k\u00f6nnen das mehrfache Allokieren von Speicher sein, was zu Folgen des Memory-Leaks weiter oben im Artikel f\u00fchren w\u00fcrde. [9]<\/p>\n\n\n\n<p>Eine einfache Race Condition k\u00f6nnte das Inkrementieren einer globalen Variable x sein, da es sich hierbei um keine atomare Operation handelt, also aus einzelnen Teilschritten besteht, welche unterbrochen werden k\u00f6nnen, wie in folgendem Beispiel gezeigt [30].<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>C++<\/th><th>MASM<\/th><th>MASM<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">++x;<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">inc dword ptr [x]<\/code><\/pre><\/td><td><pre><code class=\"\" data-line=\"\">mov eax,dword ptr [x]&lt;br&gt;inc eax&lt;br&gt;mov dword ptr [x],eax<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 8: Teilschritte beim Inkrementieren einer Variablen <\/figcaption><\/figure>\n\n\n\n<p>Der Ablauf einer m\u00f6glichen Race-Condition mit dieser Operation ist wie folgt gegeben. T1 und T2 sind zwei Threads. Die Aktion T1-1 bedeutet, dass Therad 1 die Aktion 1 ausf\u00fchrt, bezogen auf die drei Assembly-Befehle in obiger Tabelle.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Aktion<\/th><th>T1<\/th><th>T2<\/th><th>Speicher<\/th><\/tr><\/thead><tbody><tr><td>&#8211;<\/td><td>&#8211;<\/td><td>&#8211;<\/td><td>7<\/td><\/tr><tr><td>T1-1<\/td><td>7<\/td><td>&#8211;<\/td><td>7<\/td><\/tr><tr><td>T2-1<\/td><td>7<\/td><td>7<\/td><td>7<\/td><\/tr><tr><td>T2-2<\/td><td>7<\/td><td>8<\/td><td>7<\/td><\/tr><tr><td>T2-3<\/td><td>7<\/td><td>8<\/td><td>8<\/td><\/tr><tr><td>T1-2<\/td><td>8<\/td><td>8<\/td><td>8<\/td><\/tr><tr><td>T1-3<\/td><td>8<\/td><td>8<\/td><td>8<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 9: m\u00f6glicher Race-Condition-Ablauf f\u00fcr das Inkrementieren einer globalen Variable.<\/figcaption><\/figure>\n\n\n\n<p>In obigem Beispiel ist zu sehen, dass die letzte Zeile der Tabelle keine Wirkung hat, da der erste Thread noch auf einem veralteten Zustand der globalen Variablen gearbeitet hat.<\/p>\n\n\n\n<p>C und C++ sowie Java und andere Sprachen unterst\u00fctzen verschiedene Synchronisations-Mechanismen, um einen exklusiven Zugriff auf geteilte Ressourcen in einer parallel ausf\u00fchrbaren Umgebung zu erm\u00f6glichen. Atomare Operationen sind hierbei die kleinste Synchronisations-Primitive, da es sich hierbei um Synchronisation auf Instruktions-Level handelt [30]. Aus atomaren Instruktionen k\u00f6nnen Locking-Mechanismen gebaut werden, welche gr\u00f6\u00dfere Code-Bereiche f\u00fcr nur einen Thread parallel ausf\u00fchrbar machen k\u00f6nnen, um den Synchronisations-Aufwand zu reduzieren [31]. Mutexes [32] und Semaphoren [33] bieten als Synchronisations-Objekte eine angenehme Anwendung diverser Patterns aus der parallelen Programmierung wie etwa &#8216;Producer\/Consumer&#8217; [34].<\/p>\n\n\n\n<p>Aber keine der Sprachen bis auf Rust hatte bisher Mechanismen in der Sprache eingebunden, um eine Thread-sichere Entwicklung zu gew\u00e4hrleisten. Das korrekte Locking beziehungsweise Synchronisieren in C\/C++ oder Java ist Aufgabe des Entwicklers. Zum Beispiel ist nicht gew\u00e4hrleistet, dass die geteilte Ressource nicht von einer anderen Stelle der Anwendung manipuliert werden kann.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Mutexes und Locking in Rust<\/h4>\n\n\n\n<p>Dem Versucht Rust entgegenzuwirken, indem in Rust ein Mutex immer an die zu sch\u00fctzende Ressource gekoppelt ist. Wird versucht, auf die Ressource zuzugreifen, muss die Ressource \u00fcber das Mutex angefragt werden. Es wird also garantiert, dass diese Ressource nie von zwei Threads parallel zugegriffen werden kann [19].<\/p>\n\n\n\n<p>Ein weiterer Mechanismus von Rust ist das <strong>MutexGuard&lt;T&gt;<\/strong>-Objekt, welches bei der Anfrage des Mutex nach dem Lock zur\u00fcck gegeben wird. Hierbei handelt es sich um ein Wrapper-Objekt \u00e4hnlich einem Scoped-Lock. Wenn das Objekt zerst\u00f6rt, also der Kontext oder die Funktion verlassen wird, wird die Ressource wieder \u00fcber das Mutex frei gegeben. Damit werden Deadlocks durch ein fehlendes unlock() vermieden. \u00dcber das MutexGuard-Objekt kann schlie\u00dflich auf die Ressource zugegriffen werden, wobei vom Compiler zur Compile-Zeit garantiert wird, dass die Referenz auf die Ressource nicht \u00fcber die Lebenszeit des MutexGuard hinaus \u00fcberlebt. Dadurch werden zum Beispiel Fehler wie der Zugriff auf die Ressource ohne Locking \u00fcber die Referenz vermieden [19]. Folgende Tabelle zeigt die daf\u00fcr n\u00f6tigen Funktionen in Rust, um eine Ressource \u00fcber das Mutex anzufragen.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Code (Rust)<\/th><th>Beschreibung<\/th><\/tr><\/thead><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn mutex&lt;T: Send&gt;(t: T) -&gt; Mutex&lt;T&gt;;<\/code><\/pre><\/td><td>Mutex-Erzeugung<\/td><\/tr><tr><td><pre><code class=\"\" data-line=\"\">fn lock&lt;T: Send&gt;(mutex: &amp;Mutex&lt;T&gt;) -&gt; MutexGuard&lt;T&gt;;<\/code><\/pre><\/td><td>Lock-Anfrage<\/td><\/tr><tr><td><pre><code class=\"\" data-line=\"\">fn access&lt;T: Send&gt;(guard: &amp;mut MutexGuard&lt;T&gt;) -&gt; &amp;mut T;<\/code><\/pre><\/td><td>Ressourcen-Abfrage<\/td><\/tr><\/tbody><\/table><figcaption>Tabelle 10: Mutex-Funktionen in Rust aus [19].<\/figcaption><\/figure>\n\n\n\n<p>Ein entsprechender Beispielcode f\u00fcr die Abfrage einer Ressource \u00fcber das Mutex-Objekt ist wie folgt gegeben:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn fct(mutex: &amp;Mutex&lt;T&gt;){&lt;br&gt;   let mut guard = lock(mutex);&lt;br&gt;   let data = access(&amp;mut guard);&lt;br&gt;   \/\/ do something with data&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 6: Beispiel f\u00fcr Mutex-Verwendung (abgeleitet von [19])<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Thread-Spawning<\/h4>\n\n\n\n<p>Beim Erstellen von Threads bietet Rust weitere Sicherheiten, wie etwa den <strong>JoinGuard&lt;T&gt;<\/strong>. Dieses Objekt verh\u00e4lt sich \u00e4hnlich wie der Scoped-Lock, ruft aber join(), anstatt unlock() im Destruktor auf, und auch nur wenn join() nicht bereits aufgerufen wurde. Damit k\u00f6nnen Referenzen auf Speicher-Inhalte des Stacks, welche den entsprechenden Threads bei der Erzeugung mitgegeben wurden, valide gehalten werden. Beim Verlassen des Kontext wird zun\u00e4chst auf alle erstellten Threads des Kontext gewartet und anschlie\u00dfend der Stack-Speicher frei gegeben. [19]<\/p>\n\n\n\n<p>In folgendem Beispiel wird ein dynamisches Array (Vector) auf dem Stack erzeugt und bei der Erzeugung des Threads eine Referenz darauf \u00fcbergeben.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn scoped&lt;&#039;a,T&gt;(t: T) -&gt; JoinGuard&lt;&#039;a&gt; where F: &#039;a, ...&lt;br&gt;&lt;br&gt;fn fct(){&lt;br&gt;   let mut vec = Vec::new();&lt;br&gt;   let guard = thread::scoped(|| {&lt;br&gt;      fct2(&amp;vec);&lt;br&gt;   });&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 7: Beispiel f\u00fcr die Erstellung eines Therads mit &#8216;scoped&#8217;, abgeleitet von [19].<\/figcaption><\/figure>\n\n\n\n<p>Soll nicht auf erzeugte Threads gewartet, also die Funktion direkt beendet werden, kann auch eine statische Pr\u00fcfung zur Compile-Zeit stattfinden. Hier ist es nun nicht mehr erlaubt, Referenzen auf dem Stack-Speicher dem Thread bei der Erzeugung mitzugeben [19].<\/p>\n\n\n\n<p>Folgendes Beispiel w\u00fcrde nicht kompilieren und entspricht obigem Beispiel mit einer anderen Erzeugungs-Funktion &#8216;spawn&#8217;, welche die statische Pr\u00fcfung erm\u00f6glicht.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">fn spawn&lt;F&gt;(f: F) where F: &#039;static, ...&lt;br&gt;&lt;br&gt;fn fct(){&lt;br&gt;   let mut vec = Vec::new();&lt;br&gt;   thread::spawn(|| {&lt;br&gt;      fct2(&amp;vec);&lt;br&gt;   });&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption> Code 8: Beispiel f\u00fcr die Erstellung eines Therads mit &#8216;spawn&#8217;, abgeleitet von [19]. <\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Send und !Send<\/h4>\n\n\n\n<p>Rust unterscheidet beim Multi.Threading zwei unterschiedliche Typen: Send und !Send. &#8216;<strong>Send<\/strong>&#8216; sind alle Objekte beziehungsweise Datenstrukturen, aber auch Funktionen, welche Thread-safe sind, also auch von mehreren Threads parallel ausgef\u00fchrt werden k\u00f6nnen, ohne dass sich der Programmierer Gedanken machen muss. &#8216;<strong>!Send<\/strong>&#8216; hingegen werden alle Programm-Module genannt, welche nicht Thread-safe sind. Durch diese Unterscheidung kann nun eingeschr\u00e4nkt werden, welche Objekte oder Typen an welchen Bereichen der Anwendung eingesetzt werden k\u00f6nnen. [19]<\/p>\n\n\n\n<p>Zum Beispiel erlaubt die Funktion zur Erzeugung eines Mutex im obigen Beispiel &#8216; <strong>fn mutex&lt;T: Send&gt;(t: T) -&gt; Mutex&lt;T&gt;;<\/strong> &#8216; nur Daten-Typen, welche Thread-safe sind, um den exklusiven Zugriff auf die Ressource durch das Mutex gew\u00e4hrleisten zu k\u00f6nnen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Type-Safety<\/h2>\n\n\n\n<p>Typ-Sicherheit bedeutet, dass alle Typ-Verletzungen erkannt, also alle Daten-Typen gem\u00e4\u00df ihrer Definition korrekt verwendet werden. Datentypen werden hierbei meist vom Compiler statisch zur Compile-Zeit, aber auch dynamisch vom Interpreter oder der Laufzeitumgebung mittels eines Typsystems gepr\u00fcft. [20]<\/p>\n\n\n\n<p>Statische Typpr\u00fcfung f\u00fchrt in der Regel zu einer schnelleren Ausf\u00fchrung des Programmcodes, da nicht zur Laufzeit erst der entsprechende Typ gepr\u00fcft werden muss. Zus\u00e4tzlich wird die Code-Qualit\u00e4t und die Zuverl\u00e4ssigkeit der Anwendung erh\u00f6ht, da im Vornherein Programmier-Fehler durch den Compiler vermieden werden k\u00f6nnen. Zus\u00e4tzlich kann der Code leichter Refactored werden, wenn die Sprache strenger typisiert ist. [20]<\/p>\n\n\n\n<p>Dynamische Typpr\u00fcfung wird vor allem bei der Objektorientierung eingesetzt, um dynamisch und flexibel pr\u00fcfen zu k\u00f6nnen, ob eine Instanz kompatibel zum Typ ist, \u00fcber den sie angesprochen wird. Dies ist \u00fcber eine statische Typpr\u00fcfung nicht m\u00f6glich, da zur Compilezeit nicht bekannt ist, welche Objekt-Instanz sich hinter welchem Typ verbirgt. [20]<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CWE-843: Access of Resource Using Incompatible Type (&#8216;Type Confusion&#8217;)<\/h3>\n\n\n\n<p>Diese Schwachstelle wird durch wenig oder gar keine Typ-Sicherheit hervorgerufen. Durch zu wenig Typpr\u00fcfung und daher entsprechende Freiheiten, ist es m\u00f6glich, dass zum Beispiel ein Typ-1 erzeugt wird und \u00fcber Typ-2 angesprochen werden kann, obwohl diese beiden Typen nicht kompatibel zueinander sind. Das bedeutet, dass ein un der selbe Speicher-Bereich unterschiedlich interpretiert werden kann. Dies ist insbesondere dann problematisch, wenn es unbeabsichtigt passiert und somit f\u00fcr den Verwendungszweck, invalide Daten ausgelesen werden oder zu viele Daten ausgelesen werden, wenn der Datentyp gr\u00f6\u00dfer ist, als der zugegriffene Speicher-Bereich [10].<\/p>\n\n\n\n<p>Dies kann zu verschiedensten Fehlern wie Out-Of-Bounds-Zugriffen, Schadcode-Ausf\u00fchrung, Daten-Manipulation, dem Auslesen sensibler Daten oder einem Programm-Absturz f\u00fchren. [10]<\/p>\n\n\n\n<p>Ein gutes Beispiel f\u00fcr eine Typ-unsichere Sprache ist C und C++. Bei diesen Sprachen ist es m\u00f6glich einen Speicher-Bereiche unterschiedlich zu interpretieren. Die Struktur &#8216;Union&#8217; beispielsweise dient der effizienten Speicher-Ausnutzung, wenn immer nur ein Feld in der Struktur gleichzeitig ben\u00f6tigt wird. Alle Felder im &#8216;Union&#8217; beginnen an der selben Adresse im Speicher und verwenden damit den selben Speicher. Jenachdem, welchen Typ das Feld hat, auf das zugegriffen wird, wird der Speicher unterschiedlich interpretiert [35], was folgendes Beispiel aus [10] zeigt.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">union Obj {&lt;br&gt;   char *m_pBuffer;&lt;br&gt;   unsigned int m_int;&lt;br&gt;};&lt;br&gt;&lt;br&gt;void fct(){&lt;br&gt;   Obj obj;&lt;br&gt;   obj.m_pBuffer = &quot;Test&quot;;&lt;br&gt;   ++obj.m_int;&lt;br&gt;   printf(&quot;%s&quot;,obj.m_pBuffer); \/\/ &quot;est&quot;&lt;br&gt;}<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 9: Beispiel f\u00fcr eine Schwachstelle bez\u00fcglich der Typ-Sicherheit [10].<\/figcaption><\/figure>\n\n\n\n<p>Die Gefahr in obigem Beispiel zielt auf das Ver\u00e4ndern der Adresse &#8216;<strong>m_pBuffer<\/strong>&#8216; ab. Sollte &#8216;<strong>m_int<\/strong>&#8216; durch einen Angreifer manipulierbar sein, k\u00f6nnte damit die Adresse &#8216;<strong>m_pBuffer<\/strong>&#8216; vom Angreifer so ge\u00e4ndert werden, sodass diese auf einen anderen Speicher-Bereich mit evtl. sensiblen Daten oder auf invaliden Speicher zeigen, was die Anwendung zum Absturz bringen w\u00fcrde.<\/p>\n\n\n\n<p>Ein weiteres Beispiel k\u00f6nnte das Casting zwischen Pointer-Typen sein, welches bei statischer Typpr\u00fcfung komplett ohne Einschr\u00e4nkungen funktioniert, was folgender Code zeigt. Hierbei ist anzumerken, das &#8216;Type1&#8217; und &#8216;Type2&#8217; beliebige Datentypen sein k\u00f6nnen. Zur Laufzeit k\u00f6nnte jedoch die Anwendung abst\u00fcrzen wenn auf falsch interpretierte Daten zugegriffen wird.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">Type1 type1;&lt;br&gt;Type1 *pType1 = &amp;type1;&lt;br&gt;Type2 *pType2 = (Type2*)pType1;&lt;br&gt;Type2 type2 = *pType2;<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 10: Pointer-Casting in C\/C++.<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Rust-L\u00f6sung<\/h4>\n\n\n\n<p>Im sicheren Modus von Rust sind alle Casts zwischen Datentypen wohl definiert und daher auch Typ-sicher. Casts werden mithilfe des &#8216;as&#8217;-Schl\u00fcsselworts explizit angegeben. Einen sicheren Pointer wie &#8216;<strong>Box&lt;T&gt;<\/strong>&#8216; als Daten-Typ zu interpretieren, welcher inkompatibel zum Pointer ist, wird vom Rust-Compiler nicht erm\u00f6glicht [36].<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><pre><code class=\"\" data-line=\"\">let x = y as T;<\/code><\/pre><\/td><\/tr><\/tbody><\/table><figcaption>Code 11: Beispiel eines Casts in Rust [36].<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Fazit<\/h2>\n\n\n\n<p>Der Artikel hat mit Rust gezeigt, dass auch sichere System-Programmierung mittels strenger Typisierung durch den Compiler m\u00f6glich ist.<\/p>\n\n\n\n<p>Rust kann bereits zur Compilezeit h\u00e4ufig gemachte Fehler in den Bereichen Memory\/-, Thread\/- und Type-Safety verhindern, was zu einer sichereren und stabileren Anwendung mit vergleichsweise wenig Speicher-Aufwand und Nachteilen in der Laufzeit-Geschwindigkeit f\u00fchrt [19].<\/p>\n\n\n\n<p>Die Haupt-Vorteile gegen\u00fcber anderen Sprachen sind hierbei das Gew\u00e4hrleisten von Speicher-Sicherheit ohne Garbage-Collection sowie Thread-Sicherheit [19].<\/p>\n\n\n\n<p>Der unsichere Modus von Rust zeigt aber, dass es ohne unsichere Programmierung in manchen Bereichen auch nicht funktioniert, da die darunter liegende Hardware oder Betriebssystem-Kommunikation ebenfalls hoch unsicher ist und manche notwendige Aktionen vom Rust-Compiler im sicheren Modus nicht erlaubt w\u00fcrden [39].<\/p>\n\n\n\n<p>Gro\u00dfe Konzerne wie Microsoft denken bereits an eine Umstellung auf Rust [37], wodurch sich erahnen l\u00e4sst, dass Rust in Zukunft C und C++ zur\u00fcck dr\u00e4ngen k\u00f6nnte. Vermutlich wird Rust die Sprachen C oder C++ nicht komplett verdr\u00e4ngen. Sehr performance-kritische Systeme wie etwa eingebettete Systeme werden in Zukunft vermutlich weiterhin in C++, aber vor allem in C entwickelt werden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Quellen<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>] &#8220;CWE Top 25.&#8221; <a href=\"https:\/\/cwe.mitre.org\/top25\/archive\/2021\/2021_cwe_top25.html\">https:\/\/cwe.mitre.org\/top25\/archive\/2021\/2021_cwe_top25.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-787: Out-of-bounds Write&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/787.html\">https:\/\/cwe.mitre.org\/data\/definitions\/787.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-125: Out-of-bounds Read&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/125.html\">https:\/\/cwe.mitre.org\/data\/definitions\/125.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-416: Use After Free&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/416.html\">https:\/\/cwe.mitre.org\/data\/definitions\/416.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-190: Integer Overflow or Wraparound&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/190.html\">https:\/\/cwe.mitre.org\/data\/definitions\/190.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-476: NULL Pointer Dereference&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/476.html\">https:\/\/cwe.mitre.org\/data\/definitions\/476.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/119.html\">https:\/\/cwe.mitre.org\/data\/definitions\/119.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-401: Missing Release of Memory after Effective Lifetime&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/401.html\">https:\/\/cwe.mitre.org\/data\/definitions\/401.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (&#8216;Race Condition&#8217;)&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/362.html\">https:\/\/cwe.mitre.org\/data\/definitions\/362.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;CWE-843: Access of Resource Using Incompatible Type (&#8216;Type Confusion&#8217;)&#8221; <a href=\"https:\/\/cwe.mitre.org\/data\/definitions\/843.html\">https:\/\/cwe.mitre.org\/data\/definitions\/843.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Microsoft: 70 percent of all security bugs are memory safety issues&#8221; <a href=\"https:\/\/www.zdnet.com\/article\/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues\/\">https:\/\/www.zdnet.com\/article\/microsoft-70-percent-of-all-security-bugs-are-memory-safety-issues\/<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Qualys Security Advisory&#8221; <a href=\"https:\/\/www.qualys.com\/2021\/05\/04\/21nails\/21nails.txt\">https:\/\/www.qualys.com\/2021\/05\/04\/21nails\/21nails.txt<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Sicherheitsupdates: Angreifer k\u00f6nnten Samba-LDAP-Server crashen&#8221; <a href=\"https:\/\/www.heise.de\/news\/Sicherheitsupdates-Angreifer-koennten-Samba-LDAP-Server-crashen-5999401.html\">https:\/\/www.heise.de\/news\/Sicherheitsupdates-Angreifer-koennten-Samba-LDAP-Server-crashen-5999401.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Apple macOS bis 11.3.0 WebKit Puffer\u00fcberlauf&#8221; <a href=\"https:\/\/vuldb.com\/de\/?id.174514\">https:\/\/vuldb.com\/de\/?id.174514<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Memory safety&#8221; <a href=\"https:\/\/en.wikipedia.org\/wiki\/Memory_safety\">https:\/\/en.wikipedia.org\/wiki\/Memory_safety<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Ariane V88&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Ariane_V88\">https:\/\/de.wikipedia.org\/wiki\/Ariane_V88<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;SafeInt-Bibliothek&#8221; <a href=\"https:\/\/docs.microsoft.com\/de-de\/cpp\/safeint\/safeint-library?view=msvc-160\">https:\/\/docs.microsoft.com\/de-de\/cpp\/safeint\/safeint-library?view=msvc-160<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Threadsicherheit&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Threadsicherheit\">https:\/\/de.wikipedia.org\/wiki\/Threadsicherheit<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Fearless Concurrency with Rust&#8221; <a href=\"https:\/\/blog.rust-lang.org\/2015\/04\/10\/Fearless-Concurrency.html\">https:\/\/blog.rust-lang.org\/2015\/04\/10\/Fearless-Concurrency.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Typsicherheit&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Typsicherheit\">https:\/\/de.wikipedia.org\/wiki\/Typsicherheit<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Rust for C++ developers &#8211; What you need to know to get rolling with crates &#8211; Pavel Yosifovich&#8221; <a href=\"https:\/\/www.youtube.com\/watch?v=k7nAtrwPhR8\">https:\/\/www.youtube.com\/watch?v=k7nAtrwPhR8<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;<code class=\"\" data-line=\"\">Rc&lt;T&gt;<\/code>, the Reference Counted Smart Pointer&#8221; <a href=\"http:\/\/web.mit.edu\/rust-lang_v1.25\/arch\/amd64_ubuntu1404\/share\/doc\/rust\/html\/book\/second-edition\/ch15-04-rc.html\">http:\/\/web.mit.edu\/rust-lang_v1.25\/arch\/amd64_ubuntu1404\/share\/doc\/rust\/html\/book\/second-edition\/ch15-04-rc.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Data Types&#8221; <a href=\"https:\/\/doc.rust-lang.org\/book\/ch03-02-data-types.html\">https:\/\/doc.rust-lang.org\/book\/ch03-02-data-types.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Module std::option&#8221; <a href=\"https:\/\/doc.rust-lang.org\/std\/option\/\">https:\/\/doc.rust-lang.org\/std\/option\/<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Box, stack and heap&#8221; <a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/std\/box.html\">https:\/\/doc.rust-lang.org\/rust-by-example\/std\/box.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;std::vector&#8221; <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/container\/vector\">https:\/\/en.cppreference.com\/w\/cpp\/container\/vector<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Struct std::vec::Vec&#8221; <a href=\"https:\/\/doc.rust-lang.org\/std\/vec\/struct.Vec.html\">https:\/\/doc.rust-lang.org\/std\/vec\/struct.Vec.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Integer overflow&#8221; <a href=\"https:\/\/en.wikipedia.org\/wiki\/Integer_overflow\">https:\/\/en.wikipedia.org\/wiki\/Integer_overflow<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Fundamental types&#8221; <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/types\">https:\/\/en.cppreference.com\/w\/cpp\/language\/types<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Atomare Operation&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Atomare_Operation\">https:\/\/de.wikipedia.org\/wiki\/Atomare_Operation<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Lock&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Lock\">https:\/\/de.wikipedia.org\/wiki\/Lock<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Mutex&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Mutex\">https:\/\/de.wikipedia.org\/wiki\/Mutex<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Semaphor (Informatik)&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Semaphor_(Informatik)\">https:\/\/de.wikipedia.org\/wiki\/Semaphor_(Informatik)<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Erzeuger-Verbraucher-Problem&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/Erzeuger-Verbraucher-Problem\">https:\/\/de.wikipedia.org\/wiki\/Erzeuger-Verbraucher-Problem<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Union declaration&#8221; <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/union\">https:\/\/en.cppreference.com\/w\/cpp\/language\/union<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Casting&#8221; <a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/types\/cast.html\">https:\/\/doc.rust-lang.org\/rust-by-example\/types\/cast.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Microsoft will Rust statt Go auch in der Cloud&#8221; <a href=\"https:\/\/www.golem.de\/news\/sichere-programmiersprache-microsoft-will-rust-statt-go-auch-in-der-cloud-2005-148235.html\">https:\/\/www.golem.de\/news\/sichere-programmiersprache-microsoft-will-rust-statt-go-auch-in-der-cloud-2005-148235.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;C (Programmiersprache)&#8221; <a href=\"https:\/\/de.wikipedia.org\/wiki\/C_(Programmiersprache)\">https:\/\/de.wikipedia.org\/wiki\/C_(Programmiersprache)<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Meet Safe and Unsafe&#8221; <a href=\"https:\/\/doc.rust-lang.org\/nomicon\/meet-safe-and-unsafe.html\">https:\/\/doc.rust-lang.org\/nomicon\/meet-safe-and-unsafe.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><li>] &#8220;Trait std::clone::Clone&#8221; <a href=\"https:\/\/doc.rust-lang.org\/std\/clone\/trait.Clone.html\">https:\/\/doc.rust-lang.org\/std\/clone\/trait.Clone.html<\/a> .Zugegriffen am: 2021-08-18.<\/li><\/ol>\n","protected":false},"excerpt":{"rendered":"<p>Motivation Ende letzten Monats (Juli, 2021) hat die CWE (Common Weakness Enumeration) einen Bericht ver\u00f6ffentlicht, welcher die Top 25 der Software-Schwachstellen aufzeigt. Es handelt sich dabei um eine Auswertung von gefundenen Schwachstellen der letzten zwei Jahre in verschiedenen Software-Systemen. Der Bericht umfasst eine Liste der 40 schwerwiegensten Schwachstellen. Dabei handelt es sich um Schwachstellen, welche [&hellip;]<\/p>\n","protected":false},"author":1013,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[26,651],"tags":[488],"ppma_author":[837],"class_list":["post-20613","post","type-post","status-publish","format-standard","hentry","category-secure-systems","category-system-designs","tag-programming-language"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":28372,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2026\/02\/18\/safeguards-in-der-ki-unterstutzten-softwareentwicklung\/","url_meta":{"origin":20613,"position":0},"title":"Safeguards in der KI-unterst\u00fctzten Softwareentwicklung","author":"Christoph Merck","date":"18. February 2026","format":false,"excerpt":"KI gest\u00fctzte Werkzeuge und autonome Agenten machen Softwareentwicklung schneller, schaffen aber neue Sicherheitsrisiken, weil sie eigenst\u00e4ndig Entscheidungen treffen und externe Tools nutzen k\u00f6nnen. Der Artikel zeigt, warum deshalb ein mehrschichtiges Safeguard Konzept n\u00f6tig ist, das klassische Ma\u00dfnahmen wie Code Reviews, Tests und statische sowie dynamische Analysen mit KI spezifischen Schutzmechanismen\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":25129,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/07\/31\/cyberangriffe-zum-anfassen-schutz-physischer-systeme-im-iot\/","url_meta":{"origin":20613,"position":1},"title":"Cyberangriffe zum Anfassen &#8211; Schutz physischer Systeme im IoT","author":"Alexander Kraus","date":"31. July 2023","format":false,"excerpt":"Das Internet of Things (IoT) - ein faszinierendes Konzept, das unser Leben und unsere Arbeitsweise revolutioniert. Es verspricht eine Welt in der nahezu alles miteinander vernetzt ist, von unseren Haushaltsger\u00e4ten bis hin zu komplexen industriellen Anlagen. Eine Zukunft, in der Effizienz und Produktivit\u00e4t in der Wirtschaft steigen und unser Alltag\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/07\/vecteezy_8136210-1280.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/07\/vecteezy_8136210-1280.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/07\/vecteezy_8136210-1280.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/07\/vecteezy_8136210-1280.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/07\/vecteezy_8136210-1280.jpg?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":27836,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/07\/24\/spezifische-angriffsvektoren-auf-die-supply-chain-von-ki-systemen\/","url_meta":{"origin":20613,"position":2},"title":"Spezifische Angriffsvektoren auf die Supply Chain von KI-Systemen","author":"Tim Ruff","date":"24. July 2025","format":false,"excerpt":"Anmerkung:\u00a0Dieser Blogpost wurde f\u00fcr das Modul Enterprise IT (113601a) verfasst. Aus Gr\u00fcnden der besseren Lesbarkeit wird in dieser Arbeit auf eine geschlechtsneutrale Differenzierung verzichtet. S\u00e4mtliche Personenbezeichnungen gelten gleicherma\u00dfen f\u00fcr alle Geschlechter. Einleitung: Bereits seit mehreren Jahren liegt ein Hauptfokus der Technologieindustrie auf der Entwicklung von K\u00fcnstlicher Intelligenz (KI) Systemen, insbesondere\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/07\/image-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/07\/image-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/07\/image-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/07\/image-2.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/07\/image-2.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":27382,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/02\/27\/tools-zur-automatischen-erstellung-von-software-bill-of-materials-sbom\/","url_meta":{"origin":20613,"position":3},"title":"Tools zur automatischen Erstellung von Software Bill of Materials (SBOM)","author":"Dorina Sobiecki","date":"27. February 2025","format":false,"excerpt":"Anmerkung: Dieser Blogpost wurde f\u00fcr das Modul Enterprise IT (113601a) verfasst. 1. Einleitung Die fortschreitende Digitalisierung und die zunehmende Vernetzung von Softwaresystemen haben Cybersicherheit zu einem zentralen Thema f\u00fcr Unternehmen, Beh\u00f6rden und Endnutzer gemacht. Transparenz \u00fcber die eingesetzten Softwarekomponenten ist dabei essenziell, um Sicherheitsl\u00fccken zu identifizieren und regulatorische Anforderungen zu\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":27821,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/07\/24\/wichtigkeit-und-praktiken-der-data-leakage-prevention\/","url_meta":{"origin":20613,"position":4},"title":"Wichtigkeit und Praktiken der Data Leakage Prevention","author":"Jonas Gehrung","date":"24. July 2025","format":false,"excerpt":"Anmerkung: Dieser Blogpost wurde f\u00fcr das Modul Enterprise IT (113601a) verfasst Die Auswirkungen eines Datenlecks k\u00f6nnen Fatal sein \u2013 Finanzielle Sch\u00e4den, Rufsch\u00e4den, aber auch rechtliche Konsequenzen k\u00f6nnen dabei in Folge entstehen. Es wird zunehmend wichtiger gegen Datenlecks etwas zu nehmen, auch weil die Anzahl von Angriffen gegen\u00fcber Organisationen und Firmen\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":20446,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/08\/14\/supply-chain-attacks\/","url_meta":{"origin":20613,"position":5},"title":"Supply Chain Attacks &#8211; Die Lieferkette schl\u00e4gt zur\u00fcck","author":"Verena Eichinger","date":"14. August 2021","format":false,"excerpt":"ein Artikel von Verena Eichinger, Amelie Kassner und Elisa Zeller Nach SolarWinds schafft es eine neue Schlagzeile aus der IT-Welt in den Massenmedien ihre Kreise zu ziehen. \u00dcber 500 Superm\u00e4rkte in Schweden mussten wegen eines Cyberangriffs schlie\u00dfen. Wie bereits bei SolarWinds handelt es sich auch hier um eine Supply Chain\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/08\/titelbild-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":837,"user_id":1013,"is_guest":0,"slug":"lk173","display_name":"Laurin Keim","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/60b6efc7d4ed4727f12ba72dc11998e5218fea7205564129792591e6a90dbc44?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/20613","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/1013"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=20613"}],"version-history":[{"count":28,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/20613\/revisions"}],"predecessor-version":[{"id":20656,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/20613\/revisions\/20656"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=20613"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=20613"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=20613"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=20613"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}