Gibt es irgendwo eine Catchall-Funktion, mit der Benutzereingaben für SQL-Injection- und XSS-Angriffe bereinigt werden können, während bestimmte Arten von HTML-Tags weiterhin zulässig sind?
php
security
xss
sql-injection
user-input
Brent
quelle
quelle
select * from users where name='$name'
spielt es keine Rolle, ob Sie PDO, MySQLi oder MySQL verwenden. Du bist immer noch in Gefahr. Sie müssen parametrisierte Abfragen verwenden oder, falls erforderlich, Escape-Mechanismen für Ihre Daten verwenden, dies ist jedoch weitaus weniger vorzuziehen.Antworten:
Es ist ein weit verbreitetes Missverständnis, dass Benutzereingaben gefiltert werden können. PHP hat sogar eine (inzwischen veraltete) "Funktion", die als magische Anführungszeichen bezeichnet wird und auf dieser Idee aufbaut. Das ist Unsinn. Vergessen Sie das Filtern (oder Reinigen oder wie auch immer die Leute es nennen).
Was Sie tun sollten, um Probleme zu vermeiden, ist ganz einfach: Wenn Sie eine Zeichenfolge in Fremdcode einbetten, müssen Sie sie gemäß den Regeln dieser Sprache maskieren. Wenn Sie beispielsweise eine Zeichenfolge in SQL-Targeting für MySQL einbetten, müssen Sie die Zeichenfolge zu diesem Zweck mit der MySQL-Funktion maskieren (
mysqli_real_escape_string
). (Bei Datenbanken ist die Verwendung vorbereiteter Anweisungen nach Möglichkeit ein besserer Ansatz.)Ein weiteres Beispiel ist HTML: Wenn Sie Zeichenfolgen in HTML-Markups einbetten, müssen Sie es mit maskieren
htmlspecialchars
. Dies bedeutet, dass jede einzelneecho
oderprint
Anweisung verwendet werden solltehtmlspecialchars
.Ein drittes Beispiel könnten Shell-Befehle sein: Wenn Sie Zeichenfolgen (z. B. Argumente) in externe Befehle einbetten und mit diesen aufrufen möchten
exec
, müssen Sieescapeshellcmd
und verwendenescapeshellarg
.Und so weiter und so fort ...
Der einzige Fall, in dem Sie Daten aktiv filtern müssen, ist, wenn Sie vorformatierte Eingaben akzeptieren. Wenn Sie beispielsweise zulassen, dass Ihre Benutzer HTML-Markups veröffentlichen, die auf der Site angezeigt werden sollen. Sie sollten dies jedoch unbedingt vermeiden, da es immer eine potenzielle Sicherheitslücke darstellt, egal wie gut Sie es filtern.
quelle
mysql_real_escape_string
ist veraltet. Es wird heutzutage als gute Praxis angesehen, vorbereitete Anweisungen zu verwenden, um eine SQL-Injection zu verhindern. Wechseln Sie also entweder zu MySQLi oder PDO.Versuchen Sie nicht, die SQL-Injection durch Bereinigen der Eingabedaten zu verhindern.
Lassen Sie stattdessen nicht zu, dass Daten zum Erstellen Ihres SQL-Codes verwendet werden . Verwenden Sie vorbereitete Anweisungen (dh die Verwendung von Parametern in einer Vorlagenabfrage), die gebundene Variablen verwenden. Nur so kann eine Garantie gegen SQL-Injection gewährleistet werden.
Weitere Informationen zum Verhindern der SQL-Injection finden Sie auf meiner Website http://bobby-tables.com/ .
quelle
Nein. Sie können Daten nicht generisch filtern, ohne einen Kontext dafür zu haben, wofür sie bestimmt sind. Manchmal möchten Sie eine SQL-Abfrage als Eingabe verwenden, und manchmal möchten Sie HTML als Eingabe verwenden.
Sie müssen Eingaben in einer Whitelist filtern - stellen Sie sicher, dass die Daten einer Spezifikation Ihrer Erwartungen entsprechen. Dann müssen Sie es maskieren, bevor Sie es verwenden, abhängig vom Kontext, in dem Sie es verwenden.
Der Prozess des Escape-Datenverkehrs für SQL - um die SQL-Injection zu verhindern - unterscheidet sich stark vom Prozess des Escape-Daten für (X) HTML, um XSS zu verhindern.
quelle
PHP hat jetzt die neuen netten filter_input-Funktionen, die Sie zum Beispiel davon befreien, den ultimativen E-Mail-Regex zu finden, da es einen integrierten FILTER_VALIDATE_EMAIL-Typ gibt
Meine eigene Filterklasse (verwendet JavaScript, um fehlerhafte Felder hervorzuheben) kann entweder durch eine Ajax-Anfrage oder einen normalen Formularbeitrag initiiert werden. (siehe das Beispiel unten)
Denken Sie natürlich daran, dass Sie Ihre SQL-Abfrage auch ausführen müssen, je nachdem, welche Art von Datenbank Sie verwenden (mysql_real_escape_string () ist beispielsweise für einen SQL-Server nutzlos). Sie möchten dies wahrscheinlich automatisch auf Ihrer entsprechenden Anwendungsebene wie einem ORM behandeln. Wie oben erwähnt: Verwenden Sie für die Ausgabe in HTML die anderen PHP-Funktionen wie HTMLspecialchars;)
Um HTML-Eingaben mit ähnlich entfernten Klassen und / oder Tags wirklich zuzulassen, ist eines der dedizierten xss-Validierungspakete erforderlich. SCHREIBEN SIE IHRE EIGENEN REGEXES NICHT, UM HTML ZU PARSEEN!
quelle
Nein, da ist kein.
Zuallererst ist die SQL-Injection ein Problem bei der Eingabefilterung, und XSS ist ein Problem, bei dem die Ausgabe nicht funktioniert. Sie würden diese beiden Vorgänge also nicht einmal gleichzeitig im Codelebenszyklus ausführen.
Grundregeln
mysql_real_escape_string()
)strip_tags()
diese Option, um unerwünschtes HTML herauszufilternhtmlspecialchars()
und beachten Sie hier den 2. und 3. Parameter.quelle
Schauen Sie sich HTML Purifier an , um das XSS-Problem zu beheben . Es ist ziemlich konfigurierbar und hat eine anständige Erfolgsbilanz.
Stellen Sie bei den SQL-Injection-Angriffen sicher, dass Sie die Benutzereingaben überprüfen und dann über mysql_real_escape_string () ausführen. Die Funktion kann jedoch nicht alle Injection-Angriffe abwehren. Daher ist es wichtig, dass Sie die Daten überprüfen, bevor Sie sie in Ihre Abfragezeichenfolge kopieren.
Eine bessere Lösung besteht darin, vorbereitete Anweisungen zu verwenden. Die PDO-Bibliothek und die mysqli-Erweiterung unterstützen diese.
quelle
PHP 5.2 führte die Funktion filter_var ein .
Es werden viele SANITIZE, VALIDATE-Filter unterstützt.
http://php.net/manual/en/function.filter-var.php
quelle
Ein Trick, der unter bestimmten Umständen hilfreich sein kann, wenn Sie eine Seite wie haben
/mypage?id=53
und die ID in einer WHERE-Klausel verwenden, besteht darin, sicherzustellen, dass die ID definitiv eine Ganzzahl ist, wie folgt:Aber das schneidet natürlich nur einen bestimmten Angriff aus, also lesen Sie alle anderen Antworten. (Und ja, ich weiß, dass der obige Code nicht großartig ist, aber er zeigt die spezifische Verteidigung.)
quelle
$id = (int)$_GET['id']
und$que = sprintf('SELECT ... WHERE id="%d"', $id)
ist auch gutVerwenden Sie moderne Versionen von MySQL und PHP.
Zeichensatz explizit festlegen:
Verwenden Sie sichere Zeichensätze:
Verwenden Sie die räumliche Funktion:
PDO :: quote () - Platziert Anführungszeichen um die Eingabezeichenfolge (falls erforderlich) und maskiert Sonderzeichen in der Eingabezeichenfolge unter Verwendung eines Anführungsstils, der dem zugrunde liegenden Treiber entspricht:
PDO-vorbereitete Anweisungen : vs MySQLi-vorbereitete Anweisungen unterstützen mehr Datenbanktreiber und benannte Parameter:
mysql_real_escape_string[veraltet in PHP 5.5.0, entfernt in PHP 7.0.0].Überprüfen Sie, ob die Variable das enthält, was Sie erwarten:
Verwenden Sie die Filterfunktion filter_var () - Filter eine Variable mit einem vorgegebenen Filter:
mehr vordefinierte Filter
quelle
Was Sie hier beschreiben, sind zwei verschiedene Probleme:
1) Benutzereingaben sollten immer als schlecht angenommen werden.
Die Verwendung vorbereiteter Anweisungen oder / und das Filtern mit mysql_real_escape_string ist definitiv ein Muss. PHP hat auch filter_input eingebaut, was ein guter Anfang ist.
2) Dies ist ein großes Thema und hängt vom Kontext der ausgegebenen Daten ab. Für HTML gibt es Lösungen wie htmlpurifier. Als Faustregel gilt immer alles, was Sie ausgeben.
Beide Themen sind viel zu groß, um in einem einzigen Beitrag behandelt zu werden, aber es gibt viele Beiträge, die detaillierter behandelt werden:
Methoden PHP-Ausgabe
Sicherere PHP-Ausgabe
quelle
Wenn Sie PostgreSQL verwenden, kann die Eingabe von PHP mit pg_escape_string () maskiert werden.
Aus der Dokumentation ( http://php.net/manual/es/function.pg-escape-string.php ):
quelle
Es gibt keine Catchall-Funktion, da mehrere Probleme zu lösen sind.
SQL Injection - Heutzutage sollte im Allgemeinen jedes PHP-Projekt vorbereitete Anweisungen über PHP Data Objects (PDO) als Best Practice verwenden, um einen Fehler durch ein streunendes Zitat sowie eine umfassende Lösung gegen Injection zu vermeiden . Dies ist auch die flexibelste und sicherste Möglichkeit, auf Ihre Datenbank zuzugreifen.
Im (einzig richtigen) PDO-Tutorial finden Sie so ziemlich alles, was Sie über PDO wissen müssen. (Herzlichen Dank an den Top-SO-Mitarbeiter @YourCommonSense für diese großartige Ressource zu diesem Thema.)
XSS - Daten auf dem Weg in ...
HTML Purifier gibt es schon lange und es wird immer noch aktiv aktualisiert. Sie können damit böswillige Eingaben bereinigen und gleichzeitig eine großzügige und konfigurierbare Whitelist mit Tags zulassen. Funktioniert hervorragend mit vielen WYSIWYG-Editoren, kann jedoch in einigen Anwendungsfällen sehr schwer sein.
In anderen Fällen, in denen wir HTML / Javascript überhaupt nicht akzeptieren möchten, fand ich diese einfache Funktion nützlich (und habe mehrere Audits gegen XSS bestanden):
/* Prevent XSS input */ function sanitizeXSS () { $_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING); $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING); $_REQUEST = (array)$_POST + (array)$_GET + (array)$_REQUEST; }
XSS - Bereinigen von Daten auf dem Weg nach draußen ... Wenn Sie nicht garantieren, dass die Daten ordnungsgemäß bereinigt wurden, bevor Sie sie Ihrer Datenbank hinzufügen, müssen Sie sie bereinigen, bevor Sie sie Ihrem Benutzer anzeigen. Wir können diese nützlichen PHP-Funktionen nutzen:
echo
oderprint
anzeigen, verwenden Sie diesehtmlspecialchars
Option , es sei denn, die Daten wurden ordnungsgemäß bereinigt und können HTML anzeigen.json_encode
ist eine sichere Möglichkeit, vom Benutzer bereitgestellte Werte von PHP bis Javascript bereitzustellenRufen Sie externe Shell-Befehle mit
exec()
odersystem()
Funktionen oder an denbacktick
Operator auf? In diesem Fall müssen Sie zusätzlich zu SQL Injection & XSS möglicherweise zusätzliche Probleme beheben, wenn Benutzer böswillige Befehle auf Ihrem Server ausführen . Sie müssen verwenden,escapeshellcmd
wenn Sie den gesamten Befehl oderescapeshellarg
einzelne Argumente maskieren möchten.quelle
mb_encode_numericentity
wird in demhtmlspecialchars
Link auf # 3 XSSDer einfachste Weg, um Fehler bei der Bereinigung von Eingaben und beim Entkommen von Daten zu vermeiden, ist die Verwendung eines PHP-Frameworks wie Symfony , Nette usw. oder eines Teils dieses Frameworks (Template-Engine, Datenbankschicht, ORM).
Bei Vorlagen-Engines wie Twig oder Latte wird die Ausgabe standardmäßig ausgeblendet. Sie müssen nicht manuell lösen, wenn Sie Ihre Ausgabe je nach Kontext ordnungsgemäß ausgeblendet haben (HTML- oder Javascript-Teil der Webseite).
Das Framework bereinigt automatisch Eingaben und Sie sollten die Variablen $ _POST, $ _GET oder $ _SESSION nicht direkt verwenden, sondern über Mechanismen wie Routing, Sitzungsbehandlung usw.
Und für die Datenbankschicht (Modellschicht) gibt es ORM-Frameworks wie Doctrine oder Wrapper um PDO wie Nette Database.
Hier können Sie mehr darüber lesen - Was ist ein Software-Framework?
quelle
Ich wollte nur hinzufügen, dass beim Thema Escape-Ausgabe, wenn Sie PHP DOMDocument verwenden, um Ihre HTML-Ausgabe zu erstellen, diese automatisch im richtigen Kontext maskiert wird. Ein Attribut (value = "") und der innere Text eines <spans> sind nicht gleich. Um sich vor XSS zu schützen, lesen Sie Folgendes : OWASP XSS Prevention Cheat Sheet
quelle
Sie bereinigen niemals Eingaben.
Sie bereinigen immer die Ausgabe.
Die Transformationen, die Sie auf Daten anwenden, um die Aufnahme in eine SQL-Anweisung zu gewährleisten, unterscheiden sich grundlegend von denen, die Sie für die Aufnahme in HTML beantragen. Sie unterscheiden sich grundlegend von denen, die Sie für die Aufnahme in Javascript beantragen. Sie unterscheiden sich grundlegend von denen, die Sie für die Aufnahme in LDIF beantragen Es unterscheidet sich grundlegend von denen, die Sie für die Aufnahme in eine E-Mail beantragen.
Überprüfen Sie auf jeden Fall die Eingabe - entscheiden Sie, ob Sie sie zur weiteren Verarbeitung akzeptieren oder dem Benutzer mitteilen möchten, dass sie nicht akzeptabel ist. Nehmen Sie jedoch keine Änderungen an der Darstellung der Daten vor, bis sie das PHP-Land verlassen.
Vor langer Zeit hat jemand versucht, einen einheitlichen Mechanismus für das Entkommen von Daten zu erfinden, und am Ende haben wir " magic_quotes " erhalten, die nicht für alle Ausgabeziele ordnungsgemäß entgangen sind und zu einer unterschiedlichen Installation geführt haben, für die unterschiedliche Codes erforderlich sind.
quelle
Vertraue niemals Benutzerdaten.
Die
trim()
Funktion entfernt Leerzeichen und andere vordefinierte Zeichen von beiden Seiten einer Zeichenfolge.Die
stripslashes()
Funktion entfernt BackslashesDie
htmlspecialchars()
Funktion konvertiert einige vordefinierte Zeichen in HTML-Entitäten.Die vordefinierten Zeichen sind:
quelle
clean_input
dann? Warum sollten Sie Schrägstriche entfernen wollen?Es gibt die Filtererweiterung ( Howto-Link , Handbuch ), die mit allen GPC-Variablen ziemlich gut funktioniert. Es ist jedoch keine magische Sache, Sie müssen es trotzdem verwenden.
quelle