Sicher Datenbankeintragungen über ein Formular machen
devian
- datenbank
Hallo alle zusammen,
ich bin gerade dabei ein Formular zu schreiben indem die Benutzer meiner Seite einen Text eingeben können und ihn anschließend über Senden in die Datenbank eintragen können.
Das Forlumar sieht vereinfacht so aus:
<form method="get" action="indatenbankeintrgaen.php">
<input id="title" type="text" name="dertext" maxLength="70">
<input type="submit" class="input" value="Senen">
</form>
Im PHP_Script empfange ich die Variable dertext mit:
if(isset($_GET['dertext'])) $dertext=$_GET['dertext'];
else $dertext="";
und speicher sie dann so in die Datenbank:
$db->query("INSERT INTO texte (dietexte) VALUES ('".addslashes($title)."');
Meine Frage lautet nun, ob dieses Vorgehen sicher genug ist und ob ich die Eintragung noch sicherer machen kann? Durch htmlspecialchars vl?
Wichtig ist mir dabei, dass User auch Sonderzeichen / * '" % & _ - etc... ohne Probleme und ohne Gefahren für mich eintragen können.
Vielen Dank für eure Hilfe! Mfg devian
Moin
und speicher sie dann so in die Datenbank:
$db->query("INSERT INTO texte (dietexte) VALUES ('".addslashes($title)."');
> Meine Frage lautet nun, ob dieses Vorgehen sicher genug ist und ob ich die Eintragung noch sicherer machen kann? Durch htmlspecialchars vl?
> Wichtig ist mir dabei, dass User auch Sonderzeichen / \* '" % & \_ - etc... ohne Probleme und ohne Gefahren für mich eintragen können.
Da fehlt noch die Behandlung des geposteten Strings bei der Speicherung mit [mysql_real_escape_string()](http://de2.php.net/manual/de/function.mysql-real-escape-string.php)
Das denke ich ist elementar.
Gruß Bobby
--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
### Henry L. Mencken ###
-> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
## Viktor Frankl ###
ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
Mahlzeit devian,
if(isset($_GET['dertext'])) $dertext=$_GET['dertext'];
else $dertext="";
Wozu das unsinnige Umkopieren in $dertext?
> und speicher sie dann so in die Datenbank:
> ~~~php
$db->query("INSERT INTO texte (dietexte) VALUES ('".addslashes($title)."');
>
Woher kommt jetzt auf einmal die Variable $title? Und wo ist die (oben gefüllte) Variable $dertext hin?
Meine Frage lautet nun, ob dieses Vorgehen sicher genug ist
Nein.
und ob ich die Eintragung noch sicherer machen kann?
Ja.
Durch htmlspecialchars vl?
Nein ... was hat das mit HTML zu tun? Beachte den (neuen) Artikel zum Thema "Kontextwechsel"!
Wichtig ist mir dabei, dass User auch Sonderzeichen / * '" % & _ - etc... ohne Probleme und ohne Gefahren für mich eintragen können.
Wieso sollten sie das nicht können? Sobald Du den an dieser Stelle stattfindenden Kontextwechsel korrekt beachtest, ist das kein Problem.
MfG,
EKKi
Woher kommt jetzt auf einmal die Variable $title? Und wo ist die (oben gefüllte) Variable $dertext hin?
Es tut mir leid, das war ein tippfehler. $tile=$dertext.
Danke für deinen Artikel ich werde Ihn mir zuherzen nehmen und ggf. hier rückmeldungen posten
Mein Code sieht nun so aus:
$db->query("INSERT INTO texte (dietexte) VALUES ('".mysql_real_escape_string($dertext)."');
Ich denke beim Datenbankeintrag verhinder ich so MYSQL_Injektionen. Fahre ich so jetzt sicherer?
Wie sieht es mit meiner URL aus? Stellt die so eine gefahr dar, wie sie gegenwärtig übergeben wird?
indatenbankeintrgaen.php?dertext=beispieltext
Ich meine, wenn ich sämtliche Datenbankeintragungen und Abfragen mit mysql_real_escape_string versehe, dürfte doch keine Gefahr mehr vorliegen?! Sehe ich das richtig?
Mahlzeit devian,
Ich denke beim Datenbankeintrag verhinder ich so MYSQL_Injektionen. Fahre ich so jetzt sicherer?
Ja. Beides.
Wie sieht es mit meiner URL aus? Stellt die so eine gefahr dar, wie sie gegenwärtig übergeben wird?
indatenbankeintrgaen.php?dertext=beispieltext
Was verstehst Du unter "eine Gefahr darstellen"? Eine Gefahr für was? Was befürchtest Du?
Ich meine, wenn ich sämtliche Datenbankeintragungen und Abfragen mit mysql_real_escape_string versehe, dürfte doch keine Gefahr mehr vorliegen?!
Beim Wechsel von PHP- zu MySQL-Kontext nicht mehr, das stimmt. Was aber ist beim Wechsel von PHP- zu HTML-Kontext (sprich: beim Auslesen der in der Datenbank gespeicherten Werte - genauer gesagt: beim Ausgeben der aus der Datenbank ausgelesenen Werte an den Browser)?
MfG,
EKKi
Beim Wechsel von PHP- zu MySQL-Kontext nicht mehr, das stimmt. Was aber ist beim Wechsel von PHP- zu HTML-Kontext (sprich: beim Auslesen der in der Datenbank gespeicherten Werte - genauer gesagt: beim Ausgeben der aus der Datenbank ausgelesenen Werte an den Browser)?
Also bei einer ganz normalen Datenbankabfrage:
$deinschulforum = $db->query_first("SELECT * FROM testtabelle WHERE spalte1='Hallo' ");
liegt meiner meinung keine Gefahr vor. Da kann kein Missbrauch entstehen. Sobald ich aber eine Variable zum Beispiel in die WHERE Bedingung einbaue wird es doch gefährlich? Bsp:
$deinschulforum = $db->query_first("SELECT * FROM testtabelle WHERE spalte1='$hallo' ");
Angenommen ich habe die Variable aus dem Formular bezogen, so wird diese ja über die URL mitübertragen. Dort kann also jeder Hans und Franz den Inhalt der Variable $hallo ändern und somit auch eine ungewollte Abfrage einleiten.
Schützt mich hier mysql_real_escape_string nicht auch?
Nun lese ich ja werte aus der Datenbank aus. Aber so sollte es ja sicher sein, denke ich.
Mahlzeit devian,
$deinschulforum = $db->query_first("SELECT * FROM testtabelle WHERE spalte1='$hallo' ");
Angenommen ich habe die Variable aus dem Formular bezogen, so wird diese ja über die URL mitübertragen. Dort kann also jeder Hans und Franz den Inhalt der Variable $hallo ändern und somit auch eine ungewollte Abfrage einleiten.
Schützt mich hier mysql_real_escape_string nicht auch?
Doch.
Nun lese ich ja werte aus der Datenbank aus. Aber so sollte es ja sicher sein, denke ich.
Wenn Du an o.g. Stelle auch mysql_real_escape_string() benutzt, dann ist der Wechsel von PHP- zu MySQL-Kontext an dieser Stelle sicher, das stimmt.
Aber was machst Du anschließend mit den aus der Datenbank ausgelesenen Werte? Du verarbeitest sie doch sicher in irgendeiner Form und gibst sie dann an den Browser aus - sprich: Du erzeugst HTML-Code. Hast Du dort auch den entsprechenden Kontextwechsel beachtet?
MfG,
EKKi
Aber was machst Du anschließend mit den aus der Datenbank ausgelesenen Werte? Du verarbeitest sie doch sicher in irgendeiner Form und gibst sie dann an den Browser aus - sprich: Du erzeugst HTML-Code. Hast Du dort auch den entsprechenden Kontextwechsel beachtet?
Ach jetzt verstehe ich was du meinst. Angenommen ich liefer mir folgenden Eintrag aus der Datenbank: '"äad/<!>
Du meinst, dass die Sonderzeichen in HTML schließlich nicht so dargestellt werden, wie sie eigentlich sein sollten, oder? Eine wirkliche Gefahr stellt dies doch nicht da? Es könne unschön aussehen, das wäre aber auch doch schon alles? Ich würde in diesem Fall vor dem Ausgeben htmlentities(), htmlspecialchars oder etwas ähnliches benutzen. Meintest du das?
Hi,
Angenommen ich liefer mir folgenden Eintrag aus der Datenbank: '"äad/<!>
Du meinst, dass die Sonderzeichen in HTML schließlich nicht so dargestellt werden, wie sie eigentlich sein sollten, oder? Eine wirkliche Gefahr stellt dies doch nicht da? Es könne unschön aussehen, das wäre aber auch doch schon alles?
Überlege dir, was passiert, wenn ich als Nutzer Text einschleusen kann, der <script>...</script> enthält, und dieser bei anderen Nutzern dann angezeigt wird.
... kann für JS-Code stehen, der die Cookies der Nutzer ausliest und an meinen Server übermittelt, oder auch gleich Nutzername und Passwort, welche sie gerade in ein Formular auf deiner Seite eingetragen haben.
Ich würde in diesem Fall vor dem Ausgeben htmlentities(), htmlspecialchars oder etwas ähnliches benutzen. Meintest du das?
Ja, natürlich.
htmlspecialchars reicht aus; htmlentities ist i.a.R. nicht zu empfehlen.
MfG ChrisB
Vielen Dank! Nun weiß ich, wie meine Seite um einiges sicherer wird! Ich werde nun immer darauf achten, wenn User etwas in die Datenbank eintragen können. mysql_real_escape_string bei eingaben und abfragen und immer schön htmlspecialchars beim ausgeben im HTML teil! Herzlichen Dank!
Hi!
Ich werde nun immer darauf achten, wenn User etwas in die Datenbank eintragen können. mysql_real_escape_string bei eingaben und abfragen und immer schön htmlspecialchars beim ausgeben im HTML teil!
So einfach ist die Sache nun auch wieder nicht. Besser wäre, wenn du das Prinzip verstehst und nicht einfach nur mit den Werkzeuge auf einfache Weise umzugehen. Nicht in allen Situationen sind sie richtig. Schau dir das Beispiel zu Zahlen an.
Lo!
Hi!
Ich werde nun immer darauf achten, wenn User etwas in die Datenbank eintragen können. mysql_real_escape_string bei eingaben und abfragen und immer schön htmlspecialchars beim ausgeben im HTML teil!
So einfach ist die Sache nun auch wieder nicht. Besser wäre, wenn du das Prinzip verstehst und nicht einfach nur mit den Werkzeuge auf einfache Weise umzugehen. Nicht in allen Situationen sind sie richtig. Schau dir das Beispiel zu Zahlen an.
Lo!
Das habe ich gelesen und ich denke schon, dass ich das prinzip verstanden habe. Bei Zahlen hilft mysql_real_escape_string ja auch, intval ist letztendlich eigentlich nur schöner oder?
Hi!
Bei Zahlen hilft mysql_real_escape_string ja auch, intval ist letztendlich eigentlich nur schöner oder?
Nein, mysql_real_escape_string() hilft nicht bei Zahlen, denn es ist für den Stringgebrauch gedacht, so wie es die letzten beiden Teile des Namens auch sagen. Wenn du in ein SQL-Statement die Zahl nackt als solche einfügst und nicht in Anführungszeichen wie einen String, dann hast du trotz mysql_real_escape_string() einen Fehler gemacht und eine Injection-Lücke. Deshalb entweder die Zahlen komplett wie Zahlen behandeln (und dabei sicherstellen, dass es Zahlen sind) oder komplett wie Strings (Anführungszeichen und mysql_real_escape_string()).
Zumindest ist das die Behandlung aus SQL-Statement-syntaktischer Sicht. Fachlich kann es ebenfalls noch Anforderungen geben, wie mit den Zahlen umgegangen werden soll.
Lo!
Okay das kann ich nachvollziehen... ich werde für die Zukunft drauf auchten, $zahlen vorher zu prüfen. Entweder mit is_numeric oder eben in der Abfrage mit intval.
Generell habe ich es mir aber auch sowieso angewöhnt und Variablen Anfürungzeichen zu setzten.
Danke nochmal