Cross-Site Scripting
Cross-Site Scripting, XSS oder arbitrary JavaScript injection ist eine Art von Computersicherheitslücken, die typischerweise in Webseiten vorkommen und es dem Angreifer ermöglichen, benutzerseitigen Programmcode in Webseiten einzufügen, die von anderen Benutzern besucht werden.
Für Informationen über Cross-Site Scripting auf der Clientseite und wie es verhindert werden kann siehe DOM-basiertes XSS .
Beispiele
Beispiele für Cross-Site Scripting:
- Der Angreifer bringt einen angemeldeten Benutzer dazu, eine speziell präparierte URL zu besuchen, oder eine Webseite, die der Angreifer kontrolliert und den Benutzer zu der präparierten URL weiterleitet.
- Die URL zeigt auf deiner Web-App und enthält JavaScript in einem String. Die Web-App fügt dieses gefährliche JavaScript wegen mangelnder Maskierung in die Seite ein und führt es bei dem Benutzer aus.
- Das JavaScript wird mit vollem Zugriff auf die Cookies des Benutzers ausgeführt. Es kann die Webseite beliebig verändern und im Namen des Benutzers Formulare ausfüllen und absenden. Das Risiko ist besonders hoch, wenn die Zielperson ein Administrator ist.
Siehe auch: Exploit examples auf Wikipedia für mehr Beispiele.
Beispiel:
function getTableCell( $out, $value ) {
$request = $out->getRequest();
$class = $request->getVal( 'class' );
return "<td class='$class'>" . htmlspecialchars( $value ) . '</td>';
}
Der Angreifer sendet dem Opfer eine URL wie:
http://example.com/wiki/SomePage?class='%20><script>hack();</script></td><td%20class='
POST requests sind auch anfällig, für auf anderen Servern gespeichertes JavaScript.
Opfer müssen dann nicht einmal direkt die infizierte Webseite öffnen. Es reicht, wenn die schädliche Webseite mit einem iframe in eine vertrauenswürdige Seite eingefügt wird. Durch URL-Verkürzer kann der manipulierte Link verschleiert werden.
Cross-Site Scripting verhindern
Um Cross-Site Scripting zu verhindern, muss Folgendes getan werden:
- Überprüfe die Eingaben
- Maskiere die Ausgaben
Du kannst die Überprüfung überspringen, aber du darfst niemals die Maskierung auslassen. Maskiere alles.
Es macht nichts, wenn Verschleierung und Überprüfung vorhanden ist, der Performanceverlust ist sehr gering im Vergleich zu der Sicherheit der Webseite. Maskierung ist auch dann wichtig, wenn die Daten von einem vertrauenswürdigen Absender kommen, die Maskierung gibt Sicherheit.
Maskiere so nah wie möglich an der Ausgabe, so kann man beim Überprüfen einfach festellen, dass die Ausgabe maskiert wurde.
Die Maskierung von Ausgaben ist kontextabhängig. Sei also des beabsichtigten Kontextes der Ausgabe bewusst und maskiere entsprechend (z. B. HTML entity, URL, JavaScript usw.)
Das OWASP Abridged XSS Prevention Cheat Sheet ist eine hilfreiche und aktuelle Referenz, um XSS-Probleme zu verhindern.
Dies gilt für alle Textformate. Wir konzentrieren uns auf HTML, da Webanwendungen sehr viel davon produzieren und die Sicherheitsprobleme besonders stark sind. Jedes Textformat sollte eine gut durchdachte Maskierungsfunktion haben.
Hier sind einige bequeme Funktionen, die HTML maskieren.
Format | Maskierungsfunktion | Hinweise |
---|---|---|
HTML | htmlspecialchars( $string, ENT_QUOTES ) | Benutze immer das ENT_QUOTES flag, das doppelte und einfache Anführungszeichen konvertiert. PHP maskiert standardmäßig leider nur einfache Anführungszeichen.[1] |
XML ID | Sanitizer::escapeId() | Für id-Attribute in HTML |
Style | Sanitizer::checkCss() | Für style-Attribute in HTML |
JavaScript | FormatJson::encode(), Xml::encodeJsVar() | |
URL-Parameter | wfArrayToCgi(), urlencode() | |
SQL | $db->addQuotes() |
MediaWiki maskierte Ausgaben
MediaWiki hat auch einige elegante Funktionen, die Ausgaben maskieren. Für SQL benutzt du die Syntax 'key' => 'value' für bedingungslos maskierte Ausgaben. Die Methoden Html:: und Xml:: maskieren Attribute, und je nach Methode werden auch Textwerte maskiert.
Externe Links
- Escaping, w3.org. Eine sehr gut geschriebene Definition des Themas.