Grundsatzfrage bei Formularüberprüfung
andreas
- php
Hallo!
Hab mal eine etwas grundsätzlichere Frage zur Formularüberprüfung. Ich meine jetzt nicht ob Javascript oder PHP, ich muß das schon mit PHP machen, da ich einige Angaben in der DB überprüfen muß. Jetzt habe ich halt dieses Formular.php, welches an script.php geschickt wird, wo dann auch die Prüfungen stattfinden müssen, und danach halt die Aktionen wie insterts....
Problem ist jetzt nur, was machen wenn was an der Eingabe zu bemängeln ist? Dann muß ich ja die Daten von Scrip.php wieder in Formular.php bekommen, damit die Daten nicht erneut ausgefüllt werden müssen. Javascript history kann ich auch nicht machen, denn da kann ich ja keine Fehlermeldung ausgeben.
Also habe ich das jetzt mit dem header gemacht, so der Art:
header ("Location: Formular.php?user=$user&Anrede=$Anrede&Vorname=$Vorname&Name=$Name&Strasse=$Strasse&PLZ=$PLZ&Ort=$Ort&Tel=$Tel&Fax=$Fax&email=$email.....&fehler=xy");
Das geht jetzt zwar, aber sind insgesamt 30 Variablen, die alle wieder mit Werten über diese URL mitgegeben werden.
Kann man das nicht irgendwie besser machen? Wie machen das die ganzen anderen Seiten? Vielleicht doch mit $PHP_SELF nur in Formular.php bleiben, und dann ggfs mit dem Header weiterleiten?
Wie macht man sowas am besten?
Grüsse
Andreas
Hallo Andreas,
wie schon selbst gesagt: Im Skript bleiben. Das ist wohl die einfachste Lösung.
Lösung 2: Irgendwo zwischenspeichern
Grüße aus Würzburg
Julian
Moin!
Problem ist jetzt nur, was machen wenn was an der Eingabe zu bemängeln ist? Dann muß ich ja die Daten von Scrip.php wieder in Formular.php bekommen, damit die Daten nicht erneut ausgefüllt werden müssen. Javascript history kann ich auch nicht machen, denn da kann ich ja keine Fehlermeldung ausgeben.
Die Idee ist, nur EIN PHP-Skript zu haben. Das hat als grobe Ausrichtung folgende Abfrage:
Wenn was gesendet wurde, dann prüfen, ob alles korrekt ist.
Wenn alles korrekt ist, dann Datenbank füllen und Ergebnisseite zeigen.
Wenn es nicht korrekt ist, oder garnichts ausgefüllt wurde, dann Formular mit Werten zeigen.
Drei nacheinander folgende IF-Abfragen, nicht verschachtelt.
Wenn du die Formularfelder ausgibst, kannst du ja mit
<input type="text" name="name" value="<?php echo $name; ?>">
den aktuell bekannten Variablenwert ausgeben. Wurde kein Formular gesendet (weil die Seite das erste Mal aufgerufen wurde), dann ist $name leer, und du kriegst auch ein leeres Formularfeld.
An dieser Lösung ist möglicherweise zu kritisieren, daß man von extern Variablenwerte einschleusen kann, aber da du ohnehin Werte prüfst, dürfte das nicht unbedingt schlimm sein. Der "Trick" ist, statt direkt auf Variablen zuzugreifen, diese aus den Hashes $HTTP_POST_VARS oder $HTTP_GET_VARS auszulesen.
Also dann <?php echo $HTTP_POST_VARS['name']; ?>. So nimmst du garantiert den Variablenwert, der per POST übermittelt wurde.
- Sven Rautenberg
Hallo,
direkt auf Variablen zuzugreifen, diese aus den Hashes $HTTP_POST_VARS oder $HTTP_GET_VARS auszulesen.
Oder im Hinblick auf aktuellste (4.1.x) und nächste Verionen von PHp gleich mit $_POST bzw. $_GET (http://www.php.net/ChangeLog-4.php).
Grüße aus Würzburg
Julian
Moin,
An dieser Lösung ist möglicherweise zu kritisieren, daß man von extern Variablenwerte einschleusen kann, aber da du ohnehin Werte prüfst, dürfte das nicht unbedingt schlimm sein. Der "Trick" ist, statt direkt auf Variablen zuzugreifen, diese aus den Hashes $HTTP_POST_VARS oder $HTTP_GET_VARS auszulesen.
Mir will immer nicht in den Kopf, warum das ein Problem sein soll. Ich meine, das ganze Skript ist doch extra dafür geschaffen worden, von extern Variablenwerte einzuschleusen, oder nicht? Es sollte also kein Problem sein, die globalen Werte zu benutzen, da man diesen eh nicht trauen kann, sie also im Zweifelsfall vom User manipuliert wurden.
Für die Variablenwerte die du selbst benutzt, _musst_ du natürlich sicherstellen, dass sie nicht vom User vorgegeben werden können, also am besten ist am Anfang des Skriptes einen Bereich zu haben, in dem man erstmal alle Variablen die man selbst benutzen will mit einem festen Wert belegt oder mit unset() behandelt. Das gilt insbesondere, falls du vorhast, die Information ob die Variablen die Eingabeprüfung korrekt überstanden haben, selbst in einer Variablen speichern willst.
Das folgende ist also eine der schlimmsten Sachen die du machen kannst:
<?php
// Variablen überprüfen
if(ist_ok($eingabe)) // oder so
$alles_klar = true;
if($alles_klar)
mysql_query(...); // Daten einfügen
?>
Noch ein wichtiger Punkt der an dem vorgeschlagenen Skript zu kritisieren ist: Die Variablen die vom User kommen, können gegebenenfalls HTML-Code oder Fragmente davon enthalten. Im einfachsten Fall geht es einfach nur schief, wenn der User ein " eingegeben hat und du die Variable in ein <input value=" "> knallst, im schlimmeren Fall handelst du dir Cross Site Scripting Probleme ein.
Also, ganz wichtig: _Alles_ was du ausgibst, und was vom User kommt ist als feindlicher HTML-Code zu betrachten und dementsprechend durch htmlentities() zu jagen. Und wo wir schon dabei sind, machen wir auch gleich noch ein stripslashes(), falls es nötig ist. Damit das nicht zuviel Aufwand machst, legst du dir dafür eine Funktion an.
Der grobe Code für dein Formular sieht also so aus:
<?php
function wp($text) { echo htmlentities( get_magic_quotes_gpc()? stripslashes($text) : $text ); }
unset($alles_klar); unset($hilfsvariable1); $fehlermeldungen=""; // ...
if($aktion == "Abschicken") {
$alles_klar = true;
if($eingabe < 0) { // Naja, oder so...
$fehlermeldungen .= "Das sollte größer 0 sein";
$alles_klar = false;
}
// evt. noch mehr überprüfungen
if($alles_klar) {
mysql_query(...) // Einfügen
// Ergebnisse anzeigen
exit();
}
}
?>
<!-- HTML-CODE -->
<?php if($fehlermeldungen!="") echo "Fehler: ".$fehlermeldungen; ?>
<form>
<input type="text" value="<?php wp($eingabe);?>">
<!--usw. usf. -->
(das hat natürlich noch Optimierungsmöglichkeiten)
Damit dürftest du einigermaßen sicher fahren. Bitte, bitte stell nicht noch ein anfälliges Formular ins Netz, davon gibt es schon genug.
--
Henryk Plötz
Grüße aus Berlin
Hi Sven
Die Idee ist, nur EIN PHP-Skript zu haben. Das hat als grobe Ausrichtung folgende Abfrage:
Meinst Du jetzt ein Script welches die Daten an sich selbst schickt und prüft, ggfs insterts macht und per Header auf Bestätigungsseite leitet? Das erscheint mir inzwischen als die beste Methode. Ich hatte erst gedacht, das Script auf die BHEstätigungsseite auszulagern, und da alle Scripte zu sammeln, was aber gar nicht so schlau ist wie ich langsam merke.
<input type="text" name="name" value="<?php echo $name; ?>">
mache ich bereits, war halt nur die Frage ob das so toll ist so viele Daten über den Header mit GET an das Formular zu übergeben.
Der "Trick" ist, statt direkt auf Variablen zuzugreifen, diese aus den Hashes $HTTP_POST_VARS oder $HTTP_GET_VARS auszulesen.
Aber da geplant ist die Werte auch mit Hilfe eines Cockies(UserID) oder auch Sessions und entsprechender DB-Abfrage die Felder zu füllen, auch werden manche Daten teilweise per GET übermittelt. Und was soll denn da passieren wenn ich die Sachen eh gut filtere?
Einziges was mir Sorgen macht ist der Dateiupload, ich hatte mal ich glaub sogar irgendwo hier im SELF-Raum ein schönes Script mit zig Überprüfungen gesehen, nur finde ich das nicht mehr(nicht das einfache, das habe ich auch gefunden). Oder weiß da jemand ein gutes oder vielleicht direkt ein paar Tips was man überprüfen sollte? Habe Max_File_Size als hidden field angegeben geht schonmal, aber da man keine Fehlermeldung bekommt muß ich das wohl auch von Hand machen. Ich weiß auch dass es immer ein Sicherheitslücke bleibt(sollen nur Bildere hochgeladen werden), aber in den Bereich kommt man so ohne weiteres nicht rein(SSL, vorher Zufallspasswort per Email erst dann Aktivierung, dann Login und auf jeder Seite neue DB-Abfrage ob in Session gespeichertes PW und Username richtig sind, sonst header... und exit; - und halt MD5 verschlüsseltes Passwort als hash mit Username angehängt, hab das alles eingebaut:-)
Wo war ich gerade? Ach ja, vielleicht hat ja jemand was für mich bzgl. Upload - Überprüfung.
Vielen Dank im voraus,
Andreas
Hi Sven
Die Idee ist, nur EIN PHP-Skript zu haben. Das hat als grobe Ausrichtung folgende Abfrage:
Meinst Du jetzt ein Script welches die Daten an sich selbst schickt und prüft, ggfs insterts macht und per Header auf Bestätigungsseite leitet? Das erscheint mir inzwischen als die beste Methode. Ich hatte erst gedacht, das Script auf die BHEstätigungsseite auszulagern, und da alle Scripte zu sammeln, was aber gar nicht so schlau ist wie ich langsam merke.
Nein, ich meinte eigentlich eher sowas:
<?
if (datengesendet)
{
datenprüfen; ...hat irgendwie zur Folge, daß
$daten_ok = true; wird
}
if ($daten_ok)
{
Daten in Datenbank eintragen
?>
<html>
<body>
<h1>Daten erfolgreich eingetragen</h1>
</body>
</html>
<?
} // Ende der Dateneintragung
if (!datengesendet oder !$daten_ok)
{
?>
<html>
<body>
<form>
<input mit Eingabedaten>
</form>
</body>
</html>
<?
} // Ende Formularausgabe
?>
Ist sehr grob, aber genau das, was du machen solltest. Zwei komplette HTML-Dateien in einem PHP-Skript. Das kannst du natürlich noch verfeinern, indem du den HTML-Head schon ganz am Anfang für beide Skriptverzweigungen identisch ausgibst, und ebenso den Fuß.
<input type="text" name="name" value="<?php echo $name; ?>">
mache ich bereits, war halt nur die Frage ob das so toll ist so viele Daten über den Header mit GET an das Formular zu übergeben.
Dann nimm POST als Formularaction. :)
Aber da geplant ist die Werte auch mit Hilfe eines Cockies(UserID) oder auch Sessions und entsprechender DB-Abfrage die Felder zu füllen, auch werden manche Daten teilweise per GET übermittelt. Und was soll denn da passieren wenn ich die Sachen eh gut filtere?
Im Intranet ist das sicherlich noch ein bißchen anders als im Internet. Gut filtern ist auf jeden Fall wichtig.
Cookies sollen Gerüchten zufolge übrigens in $HTTP_COOKIES stehen. ;) So kriegst du dann für jede Variable heraus, ob sie durch GET, POST oder Cookies erzeugt wurde, weil sie im entsprechenden Hash steht.
Einziges was mir Sorgen macht ist der Dateiupload, ich hatte mal ich glaub sogar irgendwo hier im SELF-Raum ein schönes Script mit zig Überprüfungen gesehen.
Feature-Artikel sind das Stichwort. :)
- Sven Rautenbergw