Wie verhindere ich XSS (Cross-Site Scripting) nur mit HTML und PHP?
Ich habe zahlreiche andere Beiträge zu diesem Thema gesehen, aber ich habe keinen Artikel gefunden, der klar und präzise beschreibt, wie XSS tatsächlich verhindert werden kann.
Nur ein Hinweis, dass dies den Fall nicht löst, in dem Sie Benutzereingaben als HTML-Attribut verwenden möchten. Zum Beispiel die Quell-URL eines Bildes. Kein gewöhnlicher Fall, aber leicht zu vergessen.
Es gibt einen schönen Artikel hier , die erklärt , XSS und wie man es verhindern in verschiedenen Sprachen (inkl. PHP).
XCore
Antworten:
296
Grundsätzlich müssen Sie die Funktion htmlspecialchars()immer dann verwenden, wenn Sie etwas an den Browser ausgeben möchten, das von der Benutzereingabe stammt.
Die richtige Art, diese Funktion zu verwenden, ist ungefähr so:
@ TimTim: In den meisten Fällen ja. Wenn Sie jedoch HTML-Eingaben zulassen müssen, wird es etwas schwieriger, und wenn dies der Fall ist, empfehle ich Ihnen, etwas wie htmlpurifier.org
Alix Axel
@Alix Axel, so ist die Antwort htmlspecialchars zu verwenden oder verwenden htmlpurifier.org ?
TimTim
3
Wenn Sie HTML-Eingaben akzeptieren müssen, verwenden Sie HTML Purifier, falls nicht htmlspecialchars().
Meistens ist es richtig, aber es ist nicht so einfach. Sie sollten in Betracht ziehen, nicht vertrauenswürdige Zeichenfolgen in HTML, Js, Css und nicht vertrauenswürdige HTML in HTML einzufügen. Schauen Sie sich das an: owasp.org/index.php/…
Bronzemann
41
Eine meiner Lieblingsreferenzen bei OWASP ist das Cross-Site Scripting Erklärung für denn obwohl es eine große Anzahl von XSS-Angriffsvektoren gibt, kann das Befolgen einiger Regeln die Mehrheit von ihnen stark verteidigen!
Einer der wichtigsten Schritte besteht darin, Benutzereingaben zu bereinigen, bevor sie verarbeitet und / oder an den Browser zurückgegeben werden. PHP hat einige " Filter " " -Funktionen, die verwendet werden können.
Die Form, die XSS-Angriffe normalerweise haben, besteht darin, einen Link zu einem externen Javascript einzufügen, das böswillige Absichten für den Benutzer enthält. Lesen Sie mehr darüber hier .
Sie möchten auch Ihre Website testen - ich kann das Firefox-Add-On XSS Me empfehlen .
Was brauche ich, um sicherzustellen, dass ich die Eingabe genau bereinige? Gibt es ein bestimmtes Zeichen / eine bestimmte Zeichenfolge, auf die ich achten muss?
TimTim
27
@ TimTim - nein. Alle Benutzereingaben sollten immer als inhärent feindlich angesehen werden.
Zombat
Außerdem können interne Daten (Mitarbeiter, Systemadministrator usw.) unsicher sein. Sie sollten die mit Interpretation angezeigten Daten (mit Protokolldatum und Benutzer) identifizieren und überwachen.
Samuel Dauzon
9
In der Reihenfolge der Präferenz:
Wenn Sie eine Template-Engine (z. B. Twig, Smarty, Blade) verwenden, überprüfen Sie, ob diese eine kontextsensitive Escape-Funktion bietet. Ich weiß aus Erfahrung, dass Twig es tut.{{ var|e('html_attr') }}
Wenn Sie HTML zulassen möchten, verwenden Sie HTML Purifier . Selbst wenn Sie glauben, nur Markdown oder ReStructuredText zu akzeptieren, möchten Sie den HTML-Code dieser Markup-Sprachen bereinigen.
Verwenden Sie andernfalls htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)und stellen Sie sicher, dass der Rest Ihres Dokuments denselben Zeichensatz wie verwendet $charset. In den meisten Fällen,'UTF-8' ist der gewünschte Zeichensatz.
Cross-Posting als konsolidierte Referenz aus der SO-Dokumentation Beta, die offline geschaltet wird.
Problem
Cross-Site-Scripting ist die unbeabsichtigte Ausführung von Remotecode durch einen Webclient. Jede Webanwendung kann sich XSS aussetzen, wenn sie Eingaben von einem Benutzer entgegennimmt und diese direkt auf einer Webseite ausgibt. Wenn die Eingabe HTML oder JavaScript enthält, kann Remotecode ausgeführt werden, wenn dieser Inhalt vom Webclient gerendert wird.
Wenn beispielsweise eine Seite eines Drittanbieters eine JavaScript-Datei enthält:
Das JavaScript eines Drittanbieters wird ausgeführt und der Benutzer sieht auf der Webseite "Ich laufe".
Lösung
Vertrauen Sie in der Regel niemals den Eingaben eines Kunden. Jeder GET-, POST- und Cookie-Wert kann alles sein und sollte daher validiert werden. Wenn Sie einen dieser Werte ausgeben, maskieren Sie diese, damit sie nicht auf unerwartete Weise ausgewertet werden.
Beachten Sie, dass selbst in den einfachsten Anwendungen Daten verschoben werden können und es schwierig ist, alle Quellen im Auge zu behalten. Daher wird empfohlen, die Ausgabe immer zu umgehen.
PHP bietet je nach Kontext einige Möglichkeiten, der Ausgabe zu entgehen.
htmlspecialcharskonvertiert alle "HTML-Sonderzeichen" in ihre HTML-Codierungen, was bedeutet, dass sie dann nicht als Standard-HTML verarbeitet werden. So beheben Sie unser vorheriges Beispiel mit dieser Methode:
<?php
echo '<div>'. htmlspecialchars($_GET['input']).'</div>';// or
echo '<div>'. filter_input(INPUT_GET,'input', FILTER_SANITIZE_SPECIAL_CHARS).'</div>';
Alles innerhalb des <div>Tags wird vom Browser nicht als JavaScript-Tag interpretiert, sondern als einfacher Textknoten. Der Benutzer wird sicher sehen:
Bei der Ausgabe einer dynamisch generierten URL bietet PHP die urlencodeFunktion, gültige URLs sicher auszugeben. Wenn ein Benutzer beispielsweise Daten eingeben kann, die Teil eines anderen GET-Parameters werden:
Alle böswilligen Eingaben werden in einen verschlüsselten URL-Parameter konvertiert.
Verwendung spezialisierter externer Bibliotheken oder OWASP AntiSamy-Listen
Manchmal möchten Sie HTML oder andere Code-Eingaben senden. Sie müssen eine Liste autorisierter Wörter (weiße Liste) und nicht autorisierter Wörter (schwarze Liste) führen.
Sie können Standardlisten herunterladen, die auf der OWASP AntiSamy-Website verfügbar sind . Jede Liste ist für eine bestimmte Art von Interaktion geeignet (ebay api, tinyMCE usw.). Und es ist Open Source.
Es gibt Bibliotheken, um HTML zu filtern und XSS-Angriffe für den allgemeinen Fall zu verhindern und mindestens so gut wie AntiSamy-Listen mit sehr einfacher Verwendung auszuführen. Zum Beispiel haben Sie HTML Purifier
Viele Frameworks helfen beim Umgang mit XSS auf verschiedene Arten. Wenn Sie Ihre eigenen rollen oder XSS- Probleme haben , können wir filter_input_array (verfügbar in PHP 5> = 5.2.0, PHP 7) nutzen. Normalerweise füge ich dieses Snippet meinem SessionController hinzu, da alle Aufrufe dort vor jedem anderen Controller durchgeführt werden interagiert mit den Daten. Auf diese Weise werden alle Benutzereingaben an einem zentralen Ort bereinigt. Wenn dies zu Beginn eines Projekts oder bevor Ihre Datenbank vergiftet wird, sollten Sie zum Zeitpunkt der Ausgabe keine Probleme haben ... stoppt Müll rein, Müll raus.
/* Prevent XSS input */
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);/* I prefer not to use $_REQUEST...but for those who do: */
$_REQUEST =(array)$_POST +(array)$_GET +(array)$_REQUEST;
Mit dem obigen Befehl werden ALLE HTML- und Skript-Tags entfernt. Wenn Sie eine Lösung benötigen, die sichere Tags basierend auf einer Whitelist ermöglicht, lesen Sie HTML Purifier .
Wenn Ihre Datenbank bereits vergiftet ist oder Sie zum Zeitpunkt der Ausgabe mit XSS arbeiten möchten, empfiehlt OWASP , eine benutzerdefinierte Wrapper-Funktion für zu erstellen echound diese ÜBERALL zu verwenden, wo Sie vom Benutzer bereitgestellte Werte ausgeben:
um die serverseitige Inhaltssicherheit zu aktivieren. Weitere Informationen zu CSP (Content Security Policy) finden Sie in diesem Dokument: http://content-security-policy.com/
Insbesondere das Einrichten von CSP zum Blockieren von Inline-Skripten und externen Skriptquellen ist für XSS hilfreich.
Versuchen eval(var)Sie natürlich auch zu vermeiden , wenn Sie eines von ihnen verwenden müssen, dann versuchen Sie, JS zu maskieren, HTML zu maskieren und Sie müssen möglicherweise etwas mehr tun, aber für die Grundlagen sollte dies ausreichen.
href
odersrc
HTML-Attribut zu verhindern : stackoverflow.com/questions/19047119/…Antworten:
Grundsätzlich müssen Sie die Funktion
htmlspecialchars()
immer dann verwenden, wenn Sie etwas an den Browser ausgeben möchten, das von der Benutzereingabe stammt.Die richtige Art, diese Funktion zu verwenden, ist ungefähr so:
Die Google Code University bietet außerdem folgende sehr lehrreiche Videos zur Web-Sicherheit:
So brechen Sie Web-Software - Ein Blick auf Sicherheitslücken in Web-Software
Was jeder Ingenieur über Sicherheit wissen muss und wo man sie lernen kann
quelle
htmlspecialchars()
.Eine meiner Lieblingsreferenzen bei OWASP ist das Cross-Site Scripting Erklärung für denn obwohl es eine große Anzahl von XSS-Angriffsvektoren gibt, kann das Befolgen einiger Regeln die Mehrheit von ihnen stark verteidigen!
Dies ist PHP Security Cheat Sheet
quelle
Einer der wichtigsten Schritte besteht darin, Benutzereingaben zu bereinigen, bevor sie verarbeitet und / oder an den Browser zurückgegeben werden. PHP hat einige " Filter " " -Funktionen, die verwendet werden können.
Die Form, die XSS-Angriffe normalerweise haben, besteht darin, einen Link zu einem externen Javascript einzufügen, das böswillige Absichten für den Benutzer enthält. Lesen Sie mehr darüber hier .
Sie möchten auch Ihre Website testen - ich kann das Firefox-Add-On XSS Me empfehlen .
quelle
In der Reihenfolge der Präferenz:
{{ var|e('html_attr') }}
htmlentities($var, ENT_QUOTES | ENT_HTML5, $charset)
und stellen Sie sicher, dass der Rest Ihres Dokuments denselben Zeichensatz wie verwendet$charset
. In den meisten Fällen,'UTF-8'
ist der gewünschte Zeichensatz.Stellen Sie außerdem sicher, dass Sie bei der Ausgabe und nicht bei der Eingabe maskieren .
quelle
Cross-Posting als konsolidierte Referenz aus der SO-Dokumentation Beta, die offline geschaltet wird.
Problem
Cross-Site-Scripting ist die unbeabsichtigte Ausführung von Remotecode durch einen Webclient. Jede Webanwendung kann sich XSS aussetzen, wenn sie Eingaben von einem Benutzer entgegennimmt und diese direkt auf einer Webseite ausgibt. Wenn die Eingabe HTML oder JavaScript enthält, kann Remotecode ausgeführt werden, wenn dieser Inhalt vom Webclient gerendert wird.
Wenn beispielsweise eine Seite eines Drittanbieters eine JavaScript-Datei enthält:
Und eine PHP-Anwendung gibt direkt eine übergebene Zeichenfolge aus:
Wenn ein nicht aktivierter GET-Parameter enthält,
<script src="http://example.com/runme.js"></script>
lautet die Ausgabe des PHP-Skripts:Das JavaScript eines Drittanbieters wird ausgeführt und der Benutzer sieht auf der Webseite "Ich laufe".
Lösung
Vertrauen Sie in der Regel niemals den Eingaben eines Kunden. Jeder GET-, POST- und Cookie-Wert kann alles sein und sollte daher validiert werden. Wenn Sie einen dieser Werte ausgeben, maskieren Sie diese, damit sie nicht auf unerwartete Weise ausgewertet werden.
Beachten Sie, dass selbst in den einfachsten Anwendungen Daten verschoben werden können und es schwierig ist, alle Quellen im Auge zu behalten. Daher wird empfohlen, die Ausgabe immer zu umgehen.
PHP bietet je nach Kontext einige Möglichkeiten, der Ausgabe zu entgehen.
Filterfunktionen
PHPs Filterfunktionen erlauben die Eingabedaten an den PHP - Skript zu hygienisiert oder validiert in vielerlei Hinsicht . Sie sind nützlich beim Speichern oder Ausgeben von Client-Eingaben.
HTML-Codierung
htmlspecialchars
konvertiert alle "HTML-Sonderzeichen" in ihre HTML-Codierungen, was bedeutet, dass sie dann nicht als Standard-HTML verarbeitet werden. So beheben Sie unser vorheriges Beispiel mit dieser Methode:Würde ausgeben:
Alles innerhalb des
<div>
Tags wird vom Browser nicht als JavaScript-Tag interpretiert, sondern als einfacher Textknoten. Der Benutzer wird sicher sehen:URL-Codierung
Bei der Ausgabe einer dynamisch generierten URL bietet PHP die
urlencode
Funktion, gültige URLs sicher auszugeben. Wenn ein Benutzer beispielsweise Daten eingeben kann, die Teil eines anderen GET-Parameters werden:Alle böswilligen Eingaben werden in einen verschlüsselten URL-Parameter konvertiert.
Verwendung spezialisierter externer Bibliotheken oder OWASP AntiSamy-Listen
Manchmal möchten Sie HTML oder andere Code-Eingaben senden. Sie müssen eine Liste autorisierter Wörter (weiße Liste) und nicht autorisierter Wörter (schwarze Liste) führen.
Sie können Standardlisten herunterladen, die auf der OWASP AntiSamy-Website verfügbar sind . Jede Liste ist für eine bestimmte Art von Interaktion geeignet (ebay api, tinyMCE usw.). Und es ist Open Source.
Es gibt Bibliotheken, um HTML zu filtern und XSS-Angriffe für den allgemeinen Fall zu verhindern und mindestens so gut wie AntiSamy-Listen mit sehr einfacher Verwendung auszuführen. Zum Beispiel haben Sie HTML Purifier
quelle
Viele Frameworks helfen beim Umgang mit XSS auf verschiedene Arten. Wenn Sie Ihre eigenen rollen oder XSS- Probleme haben , können wir filter_input_array (verfügbar in PHP 5> = 5.2.0, PHP 7) nutzen. Normalerweise füge ich dieses Snippet meinem SessionController hinzu, da alle Aufrufe dort vor jedem anderen Controller durchgeführt werden interagiert mit den Daten. Auf diese Weise werden alle Benutzereingaben an einem zentralen Ort bereinigt. Wenn dies zu Beginn eines Projekts oder bevor Ihre Datenbank vergiftet wird, sollten Sie zum Zeitpunkt der Ausgabe keine Probleme haben ... stoppt Müll rein, Müll raus.
Mit dem obigen Befehl werden ALLE HTML- und Skript-Tags entfernt. Wenn Sie eine Lösung benötigen, die sichere Tags basierend auf einer Whitelist ermöglicht, lesen Sie HTML Purifier .
Wenn Ihre Datenbank bereits vergiftet ist oder Sie zum Zeitpunkt der Ausgabe mit XSS arbeiten möchten, empfiehlt OWASP , eine benutzerdefinierte Wrapper-Funktion für zu erstellen
echo
und diese ÜBERALL zu verwenden, wo Sie vom Benutzer bereitgestellte Werte ausgeben:quelle
Sie können auch einige XSS-bezogene HTTP-Antwortheader über festlegen
header(...)
Natürlich ist der XSS-Schutzmodus des Browsers aktiviert.
um die serverseitige Inhaltssicherheit zu aktivieren. Weitere Informationen zu CSP (Content Security Policy) finden Sie in diesem Dokument: http://content-security-policy.com/ Insbesondere das Einrichten von CSP zum Blockieren von Inline-Skripten und externen Skriptquellen ist für XSS hilfreich.
Eine allgemeine Liste nützlicher HTTP-Antwortheader zur Sicherheit Ihrer Webanwendung finden Sie unter OWASP: https://www.owasp.org/index.php/List_of_useful_HTTP_headers
quelle
quelle
preg_replace
wie eseval
für Ihre Eingabe verwendet wird. owasp.org/index.php/PHP_Security_Cheat_Sheet#Code_InjectionVerwenden Sie
htmlspecialchars
aufPHP
. Vermeiden Sie bei HTML die Verwendung von:element.innerHTML = “…”; element.outerHTML = “…”; document.write(…); document.writeln(…);
wo
var
wird vom Benutzer gesteuert .Versuchen
eval(var)
Sie natürlich auch zu vermeiden , wenn Sie eines von ihnen verwenden müssen, dann versuchen Sie, JS zu maskieren, HTML zu maskieren und Sie müssen möglicherweise etwas mehr tun, aber für die Grundlagen sollte dies ausreichen.quelle
Der beste Weg, um Ihre Eingabe zu schützen, ist die Verwendungsfunktion
htmlentities
. Beispiel:Weitere Informationen erhalten Sie hier .
quelle