addslashes und magic_quotes klappen nicht so wie ich will
daniel2
- php
hallo alle zusammen,
ich stehe hier vor einem problem, mit dem ich nicht recht weiterkomme:
Quotes (",') die ich in die DB schreibe werden nicht korrekt maskiert.
Ich habe dazu eine Methode, der ich die Eingaben übergebe, und die mir danach den übergebenen String maskiert und wieder zurückgibt:
function maskInput($input) {
if (!get_magic_quotes_gpc()) {
$input = addslashes($input);
}
$input = mysql_real_escape_string(trim($input));
return $input;
} // maskInput()
Falls magic_quotes deaktiviert ist, werden " und ' per addslashes() maskiert, falles es aktiviert ist geht es automatisch.
Ein String ( Hallo "Welt" ) aus einem Textfeld, den ich folgendermaßen übergebe:
$cat = $db->maskInput($cat);
und so in die DB schreibe:
$qry="INSERT INTO ".$db->tbl_pfx."blog_cat (cat_label,cat_created_by)
VALUES ('$cat','".$_SESSION['ses_user_id']."')";
steht danach genauso in der DB:
Hallo "Welt"
Eigentlich müßte da doch jetzt in jedem Fall
Hallo "Welt"
in der DB stehen, oder etwa nicht?
Werde da gerade echt nicht schlau draus...?!?
vielen dank für eure hilfe,
grüße,
daniel
function maskInput($input) {
if (!get_magic_quotes_gpc()) {
$input = addslashes($input);
}
$input = mysql_real_escape_string(trim($input));return $input;
} // maskInput()
Falls magic_quotes deaktiviert ist, werden " und ' per addslashes() maskiert, falles es aktiviert ist geht es automatisch.
magic_quotes_gpc betrifft nur Variablen, die über Post,Get,Cookie (also vom Browser an den Webserver) reinkommen. Wenn du der Funktion also einfach so nen String gibst, wird der trick nach hinten losgehen...
(vielleicht liegt da der hund begraben, denn der code scheint korrekt zu sein...)
hi,
magic_quotes_gpc betrifft nur Variablen, die über Post,Get,Cookie (also vom Browser an den Webserver) reinkommen. Wenn du der Funktion also einfach so nen String gibst, wird der trick nach hinten losgehen...
hoppla,
ja, daran lag es ;-)
Wenn ich die Variable "korrekt" übergebe, klappt alles !!!
Vielen Dank für Deine Hilfe!!
Grüße,
Daniel
echo $begrüßung;
Quotes (",') die ich in die DB schreibe ...
Was willst du mit den Quotes in der DB? Welchen triftigen Grund kannst du anführen?
Generell sollte man nur "reine" Daten abspeichern ohne irgendwelche Maskierungen für ein bestimmtes Ausgabemedium, denn wenn du dies mal später wechseln möchtest musst du umständlich hin- und hermaskieren, statt einfach nur in eine Richtung.
und so in die DB schreibe:
$qry="INSERT INTO ".$db->tbl_pfx."blog_cat (cat_label,cat_created_by)
VALUES ('$cat','".$_SESSION['ses_user_id']."')";
Das ist kein Datenbank-Befehl. Das ist Stringverarbeitung in PHP. Es ist auch für MySQL völlig uninteressant, wie irgendeine Programmiersprache was zusammenbaut. Schau dir das an, den du wirklich sendest, also echo $qry;
echo "$verabschiedung $name";
Hi,
Was willst du mit den Quotes in der DB? Welchen triftigen Grund kannst du anführen?
Ja, kann ich. Korrigiere mich wenn ich falsch liege,
aber sollte man nicht immer Anführungszeichen vor dem Schreiben in eine DB "ver-slash-en"?
Und die Slashes dann bei der Ausgabe wieder wegnehmen?
Ich dachte, das soll (u.a.) vor SQL Injections schützen,
oder bin ich da total aufm Holzweg?
Generell sollte man nur "reine" Daten abspeichern ohne irgendwelche Maskierungen für ein bestimmtes Ausgabemedium, denn wenn du dies mal später wechseln möchtest musst du umständlich hin- und hermaskieren, statt einfach nur in eine Richtung.
Naja, Umlaute usw. lass ich ja alles so drin wie es eingegebn wurde,
und wandle es nicht großartig in die entsprechenden HTML-Entitäten um.
Grüße,
Daniel
echo $begrüßung;
Was willst du mit den Quotes in der DB? Welchen triftigen Grund kannst du anführen?
Ja, kann ich. Korrigiere mich wenn ich falsch liege,
aber sollte man nicht immer Anführungszeichen vor dem Schreiben in eine DB "ver-slash-en"?
Und die Slashes dann bei der Ausgabe wieder wegnehmen?Ich dachte, das soll (u.a.) vor SQL Injections schützen,
oder bin ich da total aufm Holzweg?
Nein, nicht ganz, nur teilweise. In der Datenbank sind die Quotes wertlos und überflüssig. Es ist einfach nur darauf zu achten, dass der Befehl, den du an die DB sendest syntaktisch korrekt ist. Da bei einer SQL-Anweisung Befehlsteile und Datenteile zusammengefasst werden, muss man bei den Daten bestimmte Vorkehrungen treffen, dass diese ordnungsgemäß übertragen werden. Dazu zählt, dass Strings in Anführungszeichen zu setzen sind, damit diese von Befehlsbestandteilen unterschieden werden können. Und damit auch Anführungszeichen in den Stringdaten vorkommen können, müssen diese besonders gekennzeichnet werden (man nennt das escapen), damit dort kein Stringende erkannt wird. Was genau MySQL da sehen möchte ist im Kapitel Strings des Handbuchs zu finden. Du kannst diese Kennzeichnung per Hand vornehmen oder das der Funktion mysql_real_escape_string() überlassen.
Wenn man nicht darauf achtet, diese Anführungszeichen zu kennzeichnen, kann es vorkommen, dass Daten nicht nur als Daten sondern auch als Befehlsbestandteil an die DB gesendet werden. Und das ist zu vermeiden, da das zu Syntaxfehlern oder ungewollten Befehlen führen kann.
PHP versucht das Quotieren mittels den Magic Quotes dem Programmierer abzunehmen. Und das funktioniert aber nicht vollständig (siehe obigen Link) oder bereitet zusätzlichen Ärger.
Beispiel Affenformular: Ein Formular wird vom Benutzer ausgefüllt und zum Server gesendet. Nehmen wir an, dass es an diesen Daten etwas zu beanstanden gibt. Das Formular wird wieder mit diesen Daten angezeigt. Nun hat aber der MQ-Mechanismus zugeschlagen und vor die Anführungszeichen diese Backslashes davorgestellt. Das ist Mist, denn bei jeder weiteren Korrekturrunde vermehren die sich.
Und außerdem war vielleicht gar nicht vorgesehen, dass die Daten in eine DB geschrieben werden oder die DB hat andere Quotierungszeichen als den \ oder oder oder ...
Außerdem gibt es bei MySQL noch ein paar mehr Zeichen zu beachten als nur die ' und " (siehe obigen Link).
Deswegen ist es empfehlenswert, den MQ-Mechanismus in der Konfigurationseinstellungen auszuschalten und nur direkt vor bei der Befehlserzeugung die Daten mit mysql_real_escape_string() zu behandeln oder eben entsprechend dem jeweiligen Ausgabemedium (HTML = htmpspecialchars(), URL = urlencode(), ...).
Wenn man keinen Einfluss auf die Konfiguration hat, sollte man einmalig am Scriptanfang und in Abhängigkeit von get_magic_quotes_gpc() alle drei GPC-Variablen durch stripslashes_deep() aus Beispiel 2 der stripslashes()-Handbuchseite schicken.
Zu dem Magic Quotes gibt es auch ein paar Handbuchseiten, die den Sinn und das Für und Wider der MQs beschreiben.
Naja, Umlaute usw. lass ich ja alles so drin wie es eingegebn wurde,
und wandle es nicht großartig in die entsprechenden HTML-Entitäten um.
Siehe oben. Das ist auch richtig so. Denn wenn du diese Daten mal nicht für HTML-Seiten verwenden willst, dann hast du dort Entities drin, die du erst wieder umwandeln musst ... wird es irgendwann unübersichtlich
echo "$verabschiedung $name";
hi,
aber sollte man nicht immer Anführungszeichen vor dem Schreiben in eine DB "ver-slash-en"?
man sollte sonderzeichen maskieren, ja.
aber in diesem falle nicht mit addslashes, sondern mit mysql_real_escape_string() bzw. mysql_escape_string().
diese beiden funktionen sind genau dafür da, eingaben vor dem einsetzen in eine mysql-query abzusichern.
_wenn_ magic_quotes_gpc aktiv ist, solltest du vorher strip_slashes() auf die daten anwenden - um sie in der "reinen" form zu erhalten, ohne irgendwelchen ge-slash-ten unsinn.
anschließend wendest du, undabhängig davon ob magic_quotes_gpc nun aktiv war und du deshalb ent-slash-t hast, mysql_(real_)escape_string darauf an.
_so_ und _nicht anders_.
Und die Slashes dann bei der Ausgabe wieder wegnehmen?
das ist ein generelles missverständnis, dem man überraschender weise sehr oft begegnet.
die daten werden nur deshalb maskiert, damit die _eingabeschnittstelle_ der datenbank sie nicht falsch versteht bzw. missinterpretiert.
in den daten, die dann letztendlich in der datenbank _landen_, sind diese maskierungen dann schon gar nicht mehr vorhanden.
eine "demaskierung" bei der ausgabe ist also nicht erforderlich. (ja, es gibt an dieser stelle sonderfälle, beispielsweise wenn magic_quotes_runtime aktiviert wäre - dann würden u.U. vor der rückgabe der daten an PHP wieder maskierungen vorgenommen. aber magic_quotes_runtime ist per default deaktiviert.)
gruß,
wahsaga