vorige Präsentation: A2 - Cryptographic Failures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation A4 - Insecure design
Auf Platz 3 der OWASP Top 10 2021: Injection
Injection-Schwachstellen tauchen auf, wenn eine Anwendung nicht vertrauenswürdige Daten an einen Interpreter weiterleitet. Injection Schwachstellen sind weit verbreitet, wir haben schon SQL-Injection und Cross Site Scripting (XSS) kennen gelernt.
Wir haben im Kapitel PHP DB Schreiben → Löschen schon SQL Injection behandelt. Zur Verhinderung von SQL-Injection stellen Datenbanken Prepared Statements zur Verfügung. In PHP können wir sie so verwenden:
$query = $dbh->prepare('SELECT * FROM users WHERE id=?'); $query->execute(array( $_GET['pid'] ) );
Mit dem prepare
wird das SQL-Statement an die Datenbank geschickt,
und dort bereits vor-kompiliert. Die Daten,
die als Input vom User/der Userin kommen werden mit execute
an die Datenbank
übergeben. In diesem zweiten Schritt können sie aber nur mehr als
Daten, nicht mehr als SQL interpretiert werden.
Eine zweite Schreibweise für prepared Statement ist noch besser lesbar: dabei werden statt der Fragezeichen benannte Platzhalter verwendet:
$stm = $dbh->prepare ( 'SELECT * FROM USERS WHERE USERNAME LIKE :name' ); $stm->bindParam(':name', $_POST['name'] ); $stm->execute();
Man kann auch mit prepared statments noch Code schreiben, der für Injections anfällig ist. Wenn man nämlich im String der an prepare übergeben wird Variablen einbettet:
$stm = $dbh->prepare ( "UPDATE users SET newsletter = ? WHERE USERNAME = '$name'" ); $query->execute(array( $_GET['newsletter'] ) ); $stm->execute();
Die OWASP empfiehlt:
Im dritten und schlechtesten Fall ist weiter zu beachten:
Unabhängig von den oben genannten Punkt gilt noch die Empfehlung:
Diese Attacke haben wir schon im Kapitel Daten Editieren besprochen:
Diese Attacke erfolgt nicht direkt (AngreiferIn : Opfer), sondern es braucht drei Personen:
Es ist also nicht die Webseite der Hackerin, die hier gefährlich ist, sondern eine andere, scheinbar harmlose Seite.
Cross Site Scripting kann komplett vermieden werden, wenn man niemals Input von BenutzerInnen auf der Webseite wiedergibt. Das ist ein seltener, aber sehr sicherer Fall.
XSS vermeiden kann man mit zwei Verteidigungs-Linien:
Achtung: der PHP Befehl strip_tags
entfernt keine Attribute aus erlaubten Tags, es ist
also ganz leicht möglich Javascript in einem onmouseover
Attribut einzuschummeln.
Statt dessen sollte man einen HTML-Filter wie HTML Purifier verwenden.
Je nachdem in welchem Kontext man Daten ausgibt muss man verschiedenes Escaping verwenden. Drei Beispiele, und die dafür passenden PHP-Befehle:
urlencode
htmlspecialchars
json_encode
Es gibt aber noch viele andere Kontexte: XML, PDF, … jedes Format hat seine eigenen Regeln.
Wann soll ich die Daten escapen: möglichst früh, direkt nach der Eingabe, oder möglichst spät, erst bei der Ausgabe?
Die Antwort ergibt sich aus den eben beschriebenen verschiedenen Kontexten:
Bei der Eingabe weiss ich noch nicht, in welchem Kontext die Daten später verwendet werden. Ich speichere die Daten in einem möglichst neutralen Format in der Datenbank. Bei der Ausgabe kenne ich den Kontext, und kann die richtige Escape-Funktion wählen.
Die Content Security Policy ist eine moderne Sicherheitsmaßnahme um XSS zu verhindern.
Die Content Security Policy wird als Header im HTTP Response oder als META-Tag in HTML and den Client übermittelt. Aktuelle Browser halten die Policy ein.
Ein Beispiel für den HTTP Header: Content-Security-Policy: default-src https:
Im HTML Code kann man den Meta-Tag mit Attribut http-equiv
verwenden,
um dieselbe Policy zu setzen:
<meta http-equiv="Content-Security-Policy" content="default-src https:">
Diese Policy bewirkt zwei Dinge:
eval
sind deaktiviertFalls man script-Tags im HTML zulassen will, kann man die option unsave-inline
verwenden:
Content-Security-Policy: default-src https: 'unsafe-inline'
vorige Präsentation: A2 - Cryptographic Failures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation A4 - Insecure design
/
#