Igäl hat gesagt.:
Wie habt ihr die neue Funktion filter_input in derartige Scripts integriert? Verzichtet ihr in den entsprechenden Funktionen nun auf type casting oder settype() und dergleichen?
Ich bin, wie sheel, ebenfalls kein großer Freund der filter_*-Funktionen. (Für weitere Begründungen siehe zuletzt
hier ab etwa Post #12, auch wenn ich mich da in ein, zwei Aspekten vielleicht ein wenig verrannt hatte.) Fairerweise muss man aber sagen, dass einige Leute sie ganz gern einsetzen. Ich persönlich glaube aber, dass die Nutzer damit gewissermaßen „unsaubere“ Schnittstellen in Kauf nehmen (vgl. sheels Ausführungen so Sonderfällen und Details der filter_*-Funktionen hier im Thread).
Ich bin auch mehr ein Fan von regulären Ausdrücken, wenn es etwa darum geht, Zahlen zu erkennen. Ich nutze aus Gründen der Einfachheit aber häufig auch lediglich Typecasts, auch wenn die es beispielsweise erlauben, dass eine Eingabe wie "10foo" als int(10) interpretiert wird.
Ein typische Zeile mit Typecast wäre:
PHP:
$intParam = (isset($_POST['n']) && !is_array($_POST['n']))
? (int) $_POST['n']
: 0;
Wobei int(0) hier der Default-Wert ist, wenn der Parameter nicht oder fehlerhaft gesetzt ist.
Der Ansatz stellt verlässlich sicher, dass ich in der Anwendung zumindest den korrekten Datentypen habe. Eingaben wie "10foo" werden zwar als int(10) ausgewertet, was nicht so ganz schick ist, aber na ja.
* * *
Ich prüfe (leider) selten bis nie, ob ein String als UTF-8 NFC vorliegt, obwohl das sinnvoll wäre. Das liegt allerdings auch daran, dass ich oft an Third-Party-Code arbeite, der in der Regel
ganz andere Probleme hat. Aber das ist sicher ein Bereich, in dem wir als PHP-Community insgesamt noch Luft nach oben haben. Wobei das meines Erachtens alles nicht so einfach ist, ohne wirklich eine Utf8NfcString-PHP-Klasse oder so zu haben. Und das ist nicht wirklich absehbar. Ich glaube, dass es schwierig ist, da den sweet spot (wann und wo welcher Check) zu finden und dann auch noch immer zuverlässig zu treffen.
Ist gerade die UTF-8-NFC-Sache in anderen (Script-)Sprachen besser gelöst? Hat da jemand Vergleichswerte?
Igäl hat gesagt.:
Naja bis die Provider auf PHP7 umstellen, bin ich alt. Was ich schon gewartet habe, bis ich endlich mit PHP5 sauber OOP betreiben konnte, weil die Provider so lange an 4.x festgehalten haben... Ich konzentrier mich vorderhand noch auf PHP5 mit den Neuerungen der jüngsten Releases im Hinterkopf.
Hmm… Da regt sich in mir mittlerer Widerspruch.

Ich habe auf Anhieb keinen Anbieter gefunden, der (zumindest bei normalem Webspace) noch kein PHP 7 anbietet. Wenn du jetzt erst auf PHP 5 umsteigst, bist du – wohlwollend gesagt – ganz ganz locker 6 Jahre hinten dran. Eher erheblich mehr. Der offizielle PHP-Support für 4.x lief am 7. August 2008 aus. Mag sein, dass da eine Linux-Distribution noch einige Jahre Patches nachgepflegt hat, aber viel mehr als 2 Jahre räume ich da auch nicht ein. Die erste PHP-5-Version ist vor 12 Jahren erschienen.
Aus Sicht des gesamten PHP-Ökosystems finde ich es aber nicht falsch, zumindest noch 1-2 Jahre zu PHP 5.4+ oder PHP 5.5+ kompatibel zu sein. Dann laufen LTS-Distributionen von Debian und Ubuntu so langsam aus, die noch die entsprechenden Versionen enthalten. Das ist aber ein gänzlich anderes Argument als jenes, dass Hosting-Anbieter kein PHP 7 anbieten würden.
Wie auch immer: PHP-5-Code, der auf zwei, drei Kleinigkeiten achtet, ist vollständig aufwärtskompatibel. Es ist im Grunde PHP-7-Code, der nur gewisse Features nicht nutzt.
Igäl hat gesagt.:
Was wäre der Vorschlag wenn es aber vorderhand lediglich darum ginge XSS zu verhindern und die superglobalen $_GET und $_POST durchzuprüfen um schädlichen Input abzufangen?
So was hat im Grunde nichts bei der Validierung von Eingaben verloren, weil die Anwendung an der Stelle noch gar nicht wissen können sollte, in welchem Kontext die Daten später verwendet werden. Sicherung gegen XSS und dergleichen erledigt man sinnvollerweise erst an dem Punkt, an dem die Daten tatsächlich in HTML-Code oder SQL-Queries und dergleichen geschrieben werden.
(Edit: Natürlich nur gegen die Dinge escapen, die für den jeweiligen Kontext relevant sind. Beim Eintragen von Daten in SQL-Queries muss nicht gegen XSS abgesichert werden und umgekehrt nicht beim Eintragen in HTML gegen SQL-Injections.
http://wiki.selfhtml.org/wiki/PHP/Anwendung_und_Praxis/Kontextwechsel)
sheel hat gesagt.:
Das ü meinte ich zwar nicht direkt, aber zuerst dazu: Im Idealfall sollte das überhaupt nicht mehr vorkommen bzw. nötig sein, nämlich wenn man alles auf UTF8 (zB.) umgestellt hat.
Noch mal betont: Der Idealfall ist hier sogar auch der absolute Regelfall. Ein maskierter Umlaut im HTML-Code deutet mit an Sicherheit grenzender Wahrscheinlichkeit auf einen falschen Umgang mit Zeichenkodierungen hin. Es gibt nur sehr esoterische Anwendungsfälle, in denen ein ü vielleicht mal Sinn ergibt. Ich persönlich kenne keinen.
sheel hat gesagt.:
b) Die meisten "normalen" PHP-Funktionen haben keine Ahnung von Zeichensätzen, nur von Bytes (dokumenitert ist das natürlich nirgends, PHP eben). Einige Funktionen, wo der Inhalt von Strings wichtig ist, funktionieren daher je nach Zeichensatz einfach nicht (gar nicht, oder nicht immer, oder nur mit Sicherheitslücken). Für manche Fälle gibt es Ersatzfunktionen, aber längt nicht für alles.
Das liegt auch daran, dass viele PHP-Funktionen mehr oder weniger Mappings zu entsprechenden C-Funktionen sind. Ich stimme aber zu, dass das nicht optimal dokumentiert ist. Andererseits ist es aus Nutzersicht auch unrealistisch, anzunehmen, dass die Funktionen mit dem Zeichensatz, den man gerade will, arbeiten.
Grundsätzlich ist es sehr gut möglich, mit PHP und den
mb_*-Funktionen mit UTF-8-Strings zu arbeiten.
sheel hat gesagt.:
c) Die meisten PHP-"Programmierer" haben keine Ahnung von irgendwas
Um es gesagt zu haben: Das ist kein Alleinstellungsmerkmal von PHP.
sheel hat gesagt.:
Was das für die Praxis bedeutet?
Normalerweise triviale Sachen wie
* zwei Strings vergleichen
* ermitteln wieviel Buchstaben ein String hat
* prüfen ob ein GET-Parameter eine Zahl ist
...
werden dadurch gar nicht mehr so trivial.
Das liegt aber auch nur begrenzt an der Sprache.
sheel hat gesagt.:
Wie viele normale lesbare Buchstaben hat der String "ä" (ohne Anführungszeichen)?
Jeder Mensch würde sagen 1. PHP sagt je nach Situation und Code (normalerweise) irgendwas zwischen 1 und 14, und wenn man es als Ersteller der Eingabe unbedingt will kann man "jede" beliebige Länge erzeugen. Etwas, das wie ein einzelnes ä ausschaut, kann in strlen auch eine Million ergeben. Wirklich alles geht. (Direkt ist das eigentlich die Schuld vom Unicode-Konsortium, nicht von PHP, aber PHP fehlt eben einiges an Funktionen und guter Doku)
PHP:
var_dump(mb_strlen('ä', 'UTF-8')); // int(1), wenn das "ä" wirklich UTF-8 ist
Dass man in Unicode seltsame Eingabe-Bytesequenzen konstruieren
kann, die vielleicht aussehen wie ein "ä", kann man PHP wirklich nicht vorwerfen. Das ist nichts, was Ottonormalnutzer so schnell mal versehentlich passiert. Da muss man es schon gezielt drauf anlegen. Und dann hat man natürlich auch kein normales "ä" eingetippt, wenn man kein normales "ä" eingetippt hat.
sheel hat gesagt.:
Oder anderes Beispiel, kennst du schon Text, der höher als die Zeile ist?
Das macht den Text halt auch nicht per se zu einer Falscheingabe. Solche Fälle machen Validierung eben allgemein und sprachübergreifend (im doppelten Sinne

) schwierig, wenn man es darauf anlegt, sie verhindern zu wollen, ohne mögliche Eingaben zu sehr einzuschränken.