Michael: UPDATE unsicher?

Hallo,

ich bin auf folgendes Problem gestoßen. Ich habe eine Tabelle mit zwei Feldern (id, text). Folgende Anfrage führt auf Grund eines Fehlers dazu, dass die ganze Tabelle überschrieben wird:

$text='Beipieltext mit "doppelten" Hochkommas, die nicht über addslashes escaped worden.';
$ergebnis=mysql_query('UPDATE tabelle SET text="'.$text.'" WHERE id=1 LIMIT 1', $verbindung);

Nach diese Anweisung wurden alle Datensatze der Tabelle im Feld "text" mit "Beipieltext mit " überschrieben, da der mysql_query den Ausdruck nur bis dahin auswertet, dann scheinbar abbricht, aber dennoch die Anweisung ausführt. (mysql_error() würde eine Fehlermeldung bringen, ich weiß...)
Das Limit und die id Bedingung werden entsprechend ignoriert.

Kann man sich irgendwie dagegen schützen? Ich sehe die Gefahr vorallem darin, dass ein Nutzer von außen z.B. über ein Formular Daten einschleußen könnte, die dann die ganze Tabelle überschreiben. Ich weiß, dass die Browser normalerweise automatisch escapen, aber das kann man ja auch mit entsprechenden Tricks übergehen...

Ich kann ja schlecht nicht nochmal über alle eingehenden Formularstrings mit addslashes drübergehen...
Eine Variante wäre zunächst stripslashes() und dann gleich wieder addslashes zu nehmen: aber gibt es keine elegantere Lösung für das Problem???

Danke im Vorraus für eure Hilfe.

Mit bestem Gruß
Michael

  1. Moin!

    $ergebnis=mysql_query('UPDATE tabelle SET text="'.$text.'" WHERE id=1 LIMIT 1', $verbindung);

    Nach diese Anweisung wurden alle Datensatze der Tabelle im Feld "text" mit "Beipieltext mit " überschrieben, da der mysql_query den Ausdruck nur bis dahin auswertet, dann scheinbar abbricht, aber dennoch die Anweisung ausführt. (mysql_error() würde eine Fehlermeldung bringen, ich weiß...)

    Lass dir das resultierende SQL-Statement mal genau ausgeben (also vorher an eine Variable zuweisen, die mit echo ausgeben und dann erst ausführen).

    Mir scheint, in $text kommt die Zeichenfolge   ";   vor. Wenn diese Zeichen enthalten sind, wird der String abgebrochen, und alles andere hintendran ignoriert. mysql_escape_string() ist hier das Stichwort.

    - Sven Rautenberg

  2. Hallo Michael,

    Nach diese Anweisung wurden alle Datensatze der Tabelle im Feld "text" mit "Beipieltext mit " überschrieben, da der mysql_query den Ausdruck nur bis dahin auswertet, dann scheinbar abbricht, aber dennoch die Anweisung ausführt. (mysql_error() würde eine Fehlermeldung bringen, ich weiß...)

    warum lässt du dir die Fehlermeldung dann nicht ausgeben (und den Query gleich dazu)?

    aber gibt es keine elegantere Lösung für das Problem???

    du suchst mysql_(real_)escape_string() (->http://de.php.net/mysql_escape_string)

    Grüße aus Nürnberg
    Tobias

    --
    Selfcode: sh:( fo:) ch:? rl:( br:< n4:& ie:% mo:| va:) de:] zu:) fl:( ss:| ls:[ js:|
  3. Hello,

    ich bin auf folgendes Problem gestoßen. Ich habe eine Tabelle mit zwei Feldern (id, text). Folgende Anfrage führt auf Grund eines Fehlers dazu, dass die ganze Tabelle überschrieben wird:

    Ich kann ja schlecht nicht nochmal über alle eingehenden Formularstrings mit addslashes drübergehen...

    Nein, aber mit stripslashes(), falls notwendig. --> get_magic_quotes_gpc()
    Und dann anschließend mit der für die Datenbank vorgesehenen Escape-Funktion neu escapen, also bei MySQL mit Mysql_(real-)escape_string()

    Liebe Grüße aus http://www.braunschweig.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau
  4. Hallo Michael,

    Ich weiß, dass die Browser normalerweise automatisch escapen,

    Nein, tun sie nicht. Es gibt in PHP eine Einstellung namens magic_quotes_gpc, die alle von außen kommenden Zeichenketten automatisch mit \ versehen - was zur Folge hat, dass Du denkst, dass der Browser dies tut - das stimmt aber nicht. _Kein_ Browser kodiert " derart.

    Meiner Ansicht nach ist magic_quotes_qpc Schwachsinn. Denn der Computer kann ja nicht von Anfang an Wissen, was ich in meinem Script mit den Daten anstelle. Deswegen kontrolliere ich am Anfang von meinen Skripten, ob magic_quotes_gpc gesetzt ist und falls ja, dann wende ich stripslashes() auf alle Eingabedaten an. Dann habe ich - egal unter welcher PHP-Installation - den reinen Text, den der Benutzer senden wollte.

    Wenn ich diesen Text nun in eine Datenbank schreiben will, dann wende ich die Funktion an, die die jeweilige Datenbankerweiterung bereitstellt, um eine Zeichenkette zu kodieren. Bei MySQL ist das z.B. mysql_escape_string. Diese verhält sich zufälligerweise identisch zu addslashes; bei anderen Datenbanken wie z.B. Oracle muss man jedoch " anders schützen und deswegen gibt es da andere Funktionen. Damit kann ich sicher sein, dass die Zeichenkette mir nicht mehr in die Abfrage hineinpfuscht.

    Mein Verfahren hat den Nachteil, dass ich im Zweifel die Zeichenkette zweimal konvertiere, allerdings habe ich so die absolute Kontrolle über das, was in der Zeichenkette drin steht.

    Noch ein Tipp: Wenn Du _sowieso_ mit addslashes/stripslashes arbeitest, solltest Du _dringenst_ magic_quotes_runtime deaktivieren (falls aktiv; kann man per Funktion am Anfang des Scripts einstellen), damit Dir dieses Feature nicht ins Handwerk pfuscht; egal, ob Du nun meinen Rat mit dem im schlimmsten Fall zweimal konvertieren annimmst, oder nicht.

    Viele Grüße,
    Christian

    1. Hallo Christian,

      vielen Dank für deine professionelle Antwort. Sie hat mir sehr geholfen und alle Unklarheiten beseitigt. Dann werd ich meine Scripte mal fleißig anpassen. Man lernt doch nie aus ;-)

      Beste Grüße
      Michael

    2. Hello,

      [...] und falls ja, dann wende ich stripslashes() auf alle Eingabedaten an. Dann habe ich - egal unter welcher PHP-Installation - den reinen Text, den der Benutzer senden wollte.

      Wenn ich diesen Text nun in eine Datenbank schreiben will, dann wende ich die Funktion an, die die jeweilige Datenbankerweiterung bereitstellt, um eine Zeichenkette zu kodieren. Bei MySQL ist das z.B. mysql_escape_string. Diese verhält sich zufälligerweise identisch zu addslashes; [...]

      Nein! Tut sie nicht. Und da liegt wahrscheinlich das Problem.

      Bitte mal selber vergleichen. :-)))

      Liebe Grüße aus http://www.braunschweig.de

      Tom

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      1. Hallo Tom,

        [addslashes vs. mysql_escape_string]

        Nein! Tut sie nicht.

        Du hast Recht, ich war unpräzise, für mindestens alle Zeichen am zwischen ASCII-Wert 32 und 127 identisch.

        Und da liegt wahrscheinlich das Problem.

        Nein, in diesem Fall nicht. Das problematische Zeichen war ", was durchaus in die obrige Kategorie passt.

        Viele Grüße,
        Christian