Gibt es irgendwo eine Auffangfunktion, die gut funktioniert, um Benutzereingaben für SQL-Injection- und XSS-Angriffe zu säubern und gleichzeitig bestimmte Arten von HTML-Tags zuzulassen?
Antworten
Zu viele Anzeigen?Was Sie hier beschreiben, sind zwei verschiedene Probleme:
- Bereinigung/Filterung von Benutzereingabedaten.
- Ausweichende Ausgabe.
1) Benutzereingaben sollten immer als schlecht angesehen werden.
Die Verwendung von Prepared Statements oder/und das Filtern mit mysql_real_escape_string ist definitiv ein Muss. PHP hat auch filter_input eingebaut, was ein guter Startpunkt ist.
2) Dies ist ein umfangreiches Thema, das vom Kontext der auszugebenden Daten abhängt. Für HTML gibt es Lösungen wie den htmlpurifier. Als Faustregel gilt: Geben Sie immer alles aus, was Sie ausgeben.
Beide Themen sind viel zu umfangreich, um sie in einem einzigen Beitrag zu behandeln, aber es gibt viele Beiträge, die mehr ins Detail gehen:
Wenn Sie PostgreSQL verwenden, kann die Eingabe von PHP mit pg_escape_literal()
$username = pg_escape_literal($_POST['username']);
De la Dokumentation :
pg_escape_literal()
escaped ein Literal für die Abfrage der PostgreSQL-Datenbank. Es gibt ein escapetes Literal im PostgreSQL-Format zurück.
Sie bereinigen niemals die Eingabe.
Sie müssen die Ausgabe immer bereinigen.
Die Transformationen, die Sie auf Daten anwenden, um sie für die Aufnahme in eine SQL-Anweisung sicher zu machen, unterscheiden sich völlig von denen, die Sie für die Aufnahme in HTML anwenden, unterscheiden sich völlig von denen, die Sie für die Aufnahme in Javascript anwenden, unterscheiden sich völlig von denen, die Sie für die Aufnahme in LDIF anwenden, unterscheiden sich völlig von denen, die Sie für die Aufnahme in CSS anwenden, unterscheiden sich völlig von denen, die Sie für die Aufnahme in eine Email....
Auf jeden Fall Eingaben validieren - entscheiden, ob Sie sie zur weiteren Bearbeitung annehmen oder dem Benutzer mitteilen, dass sie nicht akzeptabel ist. Nehmen Sie jedoch keine Änderungen an der Darstellung der Daten vor, bevor sie das PHP-Land verlassen.
Vor langer Zeit hat jemand versucht, einen allgemeingültigen Mechanismus für das Escapen von Daten zu erfinden, und das Ergebnis war die " magische_Zitate "Dies führte dazu, dass die Daten nicht für alle Ausgabeziele korrekt entschlüsselt wurden und verschiedene Installationen einen anderen Code benötigten, um zu funktionieren.
Der einfachste Weg, Fehler bei der Bereinigung von Eingaben und dem Escaping von Daten zu vermeiden, ist die Verwendung eines PHP-Frameworks wie Symfony , Nette usw. oder eines Teils dieses Rahmens (Templating Engine, Datenbankschicht, ORM).
Templating-Engine wie Zweig oder Latte hat standardmäßig die Ausgabe-Escapierung aktiviert - Sie müssen nicht manuell klären, ob Sie Ihre Ausgabe je nach Kontext (HTML- oder Javascript-Teil der Webseite) richtig escaped haben.
Das Framework säubert die Eingaben automatisch und Sie sollten die Variablen $_POST, $_GET oder $_SESSION nicht direkt verwenden, sondern über Mechanismen wie Routing, Session-Handling usw.
Und für die Datenbankschicht (Modell) gibt es ORM-Frameworks wie Doctrine oder Wrapper um PDO wie Nette Database.
Mehr darüber können Sie hier lesen. Was ist ein Software-Framework?
Wollte nur hinzufügen, dass zum Thema der Ausgabe escaping, wenn Sie php DOMDocument verwenden, um Ihre HTML-Ausgabe wird es automatisch in den richtigen Kontext zu entkommen. Ein Attribut (value="") und der innere Text eines <span> sind nicht gleichzusetzen. Um vor XSS sicher zu sein, lesen Sie dies: OWASP XSS-Prävention Spickzettel
48 Stimmen
Um Sql-Injection zu vermeiden, verwendet man heutzutage PDO oder MySQLi.
97 Stimmen
Die Verwendung von PDO oder MySQLi ist nicht genug. Wenn Sie Ihre SQL-Anweisungen mit nicht vertrauenswürdigen Daten erstellen, wie
select * from users where name='$name'
dann spielt es keine Rolle, ob Sie PDO oder MySQLi oder MySQL verwenden. Sie sind immer noch in Gefahr. Sie müssen parametrisierte Abfragen verwenden oder, wenn es sein muss, Escape-Mechanismen für Ihre Daten einsetzen, aber das ist weit weniger empfehlenswert.30 Stimmen
@AndyLester Wollen Sie damit andeuten, dass jemand PDO ohne vorbereitete Anweisungen verwendet? :)
76 Stimmen
Ich will damit sagen, dass "Benutzen Sie PDO oder MySQLi" nicht genug Information ist, um Anfängern zu erklären, wie man sie sicher benutzt. Sie und ich wissen, dass vorbereitete Anweisungen wichtig sind, aber ich gehe nicht davon aus, dass jeder, der diese Frage liest, dies weiß. Deshalb habe ich die ausdrücklichen Anweisungen hinzugefügt.
0 Stimmen
Ist also die Verwendung von PDO::prepare() oder PDO::quote() in diesem Fall die richtige Antwort?
37 Stimmen
Die Bemerkung von Andy ist völlig richtig. Ich habe meine mysql-Website vor kurzem auf PDO umgestellt, weil ich dachte, dass ich nun irgendwie vor Injektionsangriffen sicher sei. Erst während des Prozesses stellte ich fest, dass einige meiner SQL-Anweisungen immer noch mit Benutzereingaben erstellt wurden. Das habe ich dann mit Prepared Statements behoben. Einem völligen Neuling ist nicht ganz klar, dass es einen Unterschied gibt, da viele Experten zwar die Verwendung von PDO erwähnen, aber nicht auf die Notwendigkeit von vorbereiteten Anweisungen hinweisen. Die Annahme ist, dass dies offensichtlich ist. Aber nicht für einen Neuling.
0 Stimmen
Ich schätze, diese Antwort funktioniert: stackoverflow.com/questions/60174/
12 Stimmen
@Christian: GhostRider und AndyLester haben Recht. Lasst uns dies eine Lektion in Kommunikation sein. Ich war einmal ein Anfänger und es war scheiße, weil Experten einfach nicht wissen, wie man kommuniziert.
1 Stimmen
Die Bemerkung von Andy ist völlig richtig. Ich habe vor kurzem meine mysql-Website auf PDO umgestellt und dachte, dass ich nun irgendwie vor Injektionsangriffen sicher sei. Erst während des Prozesses stellte ich fest, dass einige meiner SQL-Anweisungen immer noch mit Benutzereingaben erstellt wurden. Das habe ich dann mit vorbereiteten Anweisungen behoben. Für einen absoluten Neuling ist es nicht ganz klar, dass es einen Unterschied gibt, da viele Experten die Verwendung von PDO erwähnen, aber nicht näher darauf eingehen.