A3 - Injection + XSS

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.

SQL Injection

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:

Php Code Prepared Statements verhindern SQL Injection

$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.

Prepared Statement mit benannten Platzhaltern

Eine zweite Schreibweise für prepared Statement ist noch besser lesbar: dabei werden statt der Fragezeichen benannte Platzhalter verwendet:

Php Code Prepared Statements mit benanntem Parameter

$stm = $dbh->prepare ( 'SELECT * FROM USERS WHERE USERNAME LIKE :name' );
$stm->bindParam(':name', $_POST['name'] );
$stm->execute();

Prepared Statement falsch verwenden

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:

Php Code Prepared Statements falsch gmacht

$stm = $dbh->prepare ( "UPDATE users SET newsletter = ? WHERE USERNAME = '$name'" );
$query->execute(array( $_GET['newsletter'] ) );
$stm->execute();

OWASP Empfehlungen

Die OWASP empfiehlt:

  1. Den Interpreter gänzlich vermeiden, oder
  2. Eine Schnittstelle benutzen es dem Interpreter erlaubt zwischen Code und Daten zu unterscheiden (z.B., prepared statements, stored procedures in der Datenbank), oder
  3. Den Input von der Userin/dem User geeignet escapen bevor er an den Interpreter weiter gegeben wird

Im dritten und schlechtesten Fall ist weiter zu beachten:

Unabhängig von den oben genannten Punkt gilt noch die Empfehlung:

Weitere Quellen zu SQL Injection

Cross Site Scripting (XSS)

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.

Vermeidung von XSS

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:

Eingabe validieren in PHP

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.

Richtig Escapen

Je nachdem in welchem Kontext man Daten ausgibt muss man verschiedenes Escaping verwenden. Drei Beispiele, und die dafür passenden PHP-Befehle:

  1. in einer URL - urlencode
  2. in HTML - htmlspecialchars
  3. in Javascript, als Wert einer Variable - json_encode

Es gibt aber noch viele andere Kontexte: XML, PDF, … jedes Format hat seine eigenen Regeln.

Wann Escapen?

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.

Content Security Policy

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:

Falls man script-Tags im HTML zulassen will, kann man die option unsave-inline verwenden:

Content-Security-Policy: default-src https: 'unsafe-inline'

Mehr zu XSS

A3 - Injection + XSS

vorige Präsentation: A2 - Cryptographic Failures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation A4 - Insecure design

/

#