Zur Navigation

htmlentities() und htmlspecialchars()

1 Jörg Kruse

Zitat von Ranma
Zitat von Jörg
htmlentities() (oder besser htmlspecialchars()) würde ich immer erst bei der Ausgabe in HTML anwenden, weil dort alle Strings behandelt werden müssen, nicht nur die aus der Datenbank. Zum anderen kann es durchaus passieren, dass man Daten aus der Datenbank auch in Bereichen verwenden möchte, wo ein htmlentities() bzw. htmlspecialchars() wieder rückgängig gemacht werden müsste.

Kein htmlentities() bedeutet aber, sich jedem Angriff hilflos auszuliefern? Da braucht die Benutzereingabe, die entweder ein neuer Datensatz oder nur ein Suchbegriff sein kann, nur mit "> beginnen...
Oder war es "; ? Fast egal, jedenfalls muß es entschärft werden. Also kann ich nicht einfach so irgendetwas eintragen lassen.

Mit htmlentities() bzw. htmlspecialchars() sichert man keine SQL-Queries ab, sondern HTML-Code. Die beiden Funktionen sollten also auch genau dort zum Einsatz kommen, d.h. bei der Ausgabe von HTML-Code!

Und dort musst du darauf achten, dass alle Variablen, ob sie nun aus der Datenbank oder über ein Formular oder sonstwoher kommen, entsprechend behandelt werden:

<p>Aus Formular: <?php echo htmlspecialchars($_POST['bla']) ?></p>
<p>Aus Datenbank: <?php echo htmlspecialchars($row['blub']) ?></p>

Wenn die Variablen aber nicht in HTML-Code, sondern z.B. in eine (nicht-HTML-)Email ausgegeben werden, dann benötigst du dort auch kein htmlspecialchars()

Ist htmlspecialchars() nicht nur eine veraltete Version von htmlentities() ?

Nein, htmlspecialchars() kodiert nur die Metachars <, >, ", &

htmlentities() kodiert darüber hinaus alle Zeichen, die nicht im ASCII-Zeichensatz vorkommen (wie z.B. deutsche Umlaute). Letzteres ist aber nicht notwendig, wenn die Webseite die korrekte Kodierung angibt, z.B.:

<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 

14.12.2015 20:29 | geändert: 14.12.2015 20:30

2 Ranma (Gast)


Mit htmlentities() bzw. htmlspecialchars() sichert man keine SQL-Queries ab, sondern HTML-Code. Die beiden Funktionen sollten also auch genau dort zum Einsatz kommen, d.h. bei der Ausgabe von HTML-Code!

Zunächst müssen Daten eingesammelt werden. Dafür habe ich inzwischen drei Wege vorgesehen, nämlich Listen aus Dateien, eingesammelt durch einen Crawler und schließlich noch durch die Eingabe von Daten durch Dritte in ein Formular. Soweit mir bekannt ist, muß ein Formular immer eine HTML-Ausgabe sein, also die Eingabe dann mit htmlentities() abgesichert. Meine Sorge dabei war, daß die Daten aus den drei Quellen dadurch zueinander inkompatibel sein könnten, falls nicht alles vor der Eingabe mit htmlentities() behandelt wird. Oder ich traue tatsächlich den Werten meiner eigenen Datenbank nicht. Es sieht sogar so aus als rätst du explizit dazu, den Datensätzen aus meiner eigenen Datenbank nicht zu trauen. Aber in meiner Datenbank sollte nur drinstehen, was ich zuvor hineingelassen habe?


htmlentities() kodiert darüber hinaus alle Zeichen, die nicht im ASCII-Zeichensatz vorkommen (wie z.B. deutsche Umlaute). Letzteres ist aber nicht notwendig, wenn die Webseite die korrekte Kodierung angibt,

Nur <, >, ", & ist doch ziemlich wenig. Angeblich gibt es einige Umwege, um schädlichen Code zusammenzusetzen und deswegen filtern manche (und zwar Leute, die sich viel besser als ich mit so etwas auskennen) sämtliche nichtsichtbaren Nicht-ASCII-Zeichen aus, trauen filter_var() nicht, sondern machen Whitelisting mit preg_match() und danach kommt trotzdem noch htmlentities() aus Sicherheitsgründen zum Einsatz.
Ranma

15.12.2015 01:40

3 Jörg Kruse

Es sieht sogar so aus als rätst du explizit dazu, den Datensätzen aus meiner eigenen Datenbank nicht zu trauen. Aber in meiner Datenbank sollte nur drinstehen, was ich zuvor hineingelassen habe?

Ich empfehle, alle Daten unbehandelt in die Datenbank zu speichern, da man oft erst bei der Ausgabe weiß, wie die Daten behandelt werden müssen. Ausnahme ist natürlich der Schutz gegen eine SQL-Injection, z.B. mit mysqli_real_escape_string() oder PDO

Nur <, >, ", & ist doch ziemlich wenig.

Das sind die Metazeichen in HTML (und auch anderen XML-Dialekten), und für eine sichere Ausgabe in HTML-Code ist es ausreichend nur diese zu kodieren

Angeblich gibt es einige Umwege, um schädlichen Code zusammenzusetzen

Schädlich in Bezug auf was? Neben der Ausgabe in HTML-Code gibt es natürlich noch andere Ausgaben, die abgesichert werden müssen, z.B. Email-Header gegen Header-Injection oder SQL-Queries gegen SQL-Injection (s.o.), oder Shell-Code in system() etc. Und jede dieser Ausgabe-Arten erfordert eine eigene spezifische Absicherung.

Betimmte Inhalte kann man auch (z.B. nach der Eingabe in ein Formular) vorfiltern, wenn diese in jeder Ausgabe einem bestimmten Format entsprechen, z.B. eine Emailadresse (mit filter_var()) oder eine Zahl (mit intval()). In manchen Fällen enthalten diese Variablen dann auch keine (für die jeweilige Ausgabe) kompromittierenden Zeichen mehr. Nichtsdestotrotz sollte bei jeder Ausgabe die Variablen nochmals entprechend kodiert / gefiltert werden. So sieht man beim Programmieren immer auf einem Blick, ob alle Variablen bei der Ausgabe auch wirklich angemessen gefiltert wurden.

15.12.2015 14:32 | geändert: 15.12.2015 14:34

Beitrag schreiben (als Gast)

Die Antwort wird nach der Überprüfung durch einen Moderator freigeschaltet.





[BBCode-Hilfe]