Ankündigung

Einklappen
Keine Ankündigung bisher.

MySQL injection: mysql_real_escape_string

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • MySQL injection: mysql_real_escape_string

    Hallo,

    wundert mich, ich habe hier im Forum noch nichts darüber gefunden?

    Egal, fange ich mal an:
    http://de.wikipedia.org/wiki/SQL-Injection

    Sollte sich eh mal jeder durchlesen.

    Bei PHP gibt es ja
    mysql_real_escape_string()

    Wobei bei Abfragen:
    PHP-Code:
    $abfrage "SELECT spalte1 FROM tabelle WHERE spalte2 = '".$_POST['spalte2Wert']."'";
    $query mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); 
    Dies benutzt werden sollte:
    PHP-Code:
    $abfrage "SELECT spalte1 FROM tabelle WHERE 
               spalte2 = '"
    .mysql_real_escape_string($_POST['spalte2Wert'])."'";
    $query mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!"); 
    Und ab PHP 5.1 folgendes:
    PHP-Code:
    $dbh->exec("INSERT INTO REGISTRY (name, value) VALUES (".$dbh->quote($name,PDO::PARAM_STR).", ".$dbh->quote($value,PDO::PARAM_INT).")"); 


    Was ich aber nicht verstanden habe, was mach denn mysql_real_escape_string wirklich mit den $_POST / $_GET Daten?
    Und was ist, wenn man diese Daten vorher fest definiert?

    Also Beispielsweise Egal ob $_POST oder $_GET. ich wandle diese generell in eine Variable $vari1=$POST['vari1']; $vari2=$POST['vari2']; um. Sind dann Injections auch möglich?

    Kennt jemand evtl. noch einen guten Link im Internet, der sich näher mit diesem Thema beschäftigt?

    Wie löst Ihr diese Dinge?

    Danke für Antworten!

    Gruß, Micha

  • #2
    Re: MySQL injection: mysql_real_escape_string

    Zitat von tekknotrip
    Und ab PHP 5.1 folgendes:
    PHP-Code:
    $dbh->exec("INSERT INTO REGISTRY (name, value) VALUES (".$dbh->quote($name,PDO::PARAM_STR).", ".$dbh->quote($value,PDO::PARAM_INT).")"); 
    Wo hast du das gelesen? Ich verwende weiterhin meine alte Syntax und Validate-Klasse.

    Was ich aber nicht verstanden habe, was mach denn mysql_real_escape_string wirklich mit den $_POST / $_GET Daten?
    Und was ist, wenn man diese Daten vorher fest definiert?
    Es verhindert, dass per SQL-Injection aus dem Wert ein Wert + neuer Befehl wird, nämlich indem
    http://de2.php.net/mysql_real_escape_string
    mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
    Du kannst die Anführungszeichen um SELECT * FROM tab WHERE x = 'wert' also nicht "verlassen" und somit den Befehl nicht durch Erweiterung nach deinem Belieben umwandeln.


    Also Beispielsweise Egal ob $_POST oder $_GET. ich wandle diese generell in eine Variable $vari1=$POST['vari1']; $vari2=$POST['vari2']; um. Sind dann Injections auch möglich?
    Du kopierst die Variablen doch nur (wovon ich übrigens nicht viel halte), warum sollte das SQL-Injection Versuche beeinflußen?

    Kennt jemand evtl. noch einen guten Link im Internet, der sich näher mit diesem Thema beschäftigt?
    Wikipedia ist doch schonmal gut erklärt. Meinst du in Bezug auf PHP? Hast du die Links unter "Weblinks" beachtet?

    Wie löst Ihr diese Dinge?
    Ich verwende meistens sprintf() um meinen SQL-Befehl zu erstellen. Da kann ich festlegen, welchen Typ die eingesetzten Variablen haben und benutze da schonmal dort wo Zahlen hingehören keine Anführungszeichen und den type specifier %u. Wenn dann jemand Mist eingibt wird sowieso eine 0 gesetzt die meistens keinen Sinn ergibt.

    Für Strings eben in meiner Validate::toString($_POST['text']) mysql_real_escape_string() verwenden, aber dort am besten nochmal mit get_magic_quotes_gpc() abfragen, ob der String über $_POST, $_GET usw. nicht bereits automatisch escaped wurde.

    Kommentar


    • #3
      Wo hast du das gelesen? Ich verwende weiterhin meine alte Syntax und Validate-Klasse.
      Auch unter dem obenstehenden Wikipedia Link.

      Bedeutet das letztenendes, um die Funktion zu verstehen
      Egal was hinter meinen definierten Variablen kommt: Ignoriere es!?

      Also z.B. aus diesem Link:
      http://webserver/cgi-bin/find.cgi?ID=42;UPDATE+USER+SET+TYPE="admin"+WHERE+ ID=23
      Wird bei dieser MySQL Abfrage:
      Code:
      $abfrage = "SELECT spalte1 FROM tabelle WHERE 
                 spalte2 = '".mysql_real_escape_string($_POST['ID'])."'";
      folgendes Ergebnis erzielt, als das der Link nichts anderes enthalten hätte ausser:


      Sprich mysql_real_escape_string kapp alles, was nicht unter mysql_real_escape_string definiert ist?


      Danke Dir schon jetzt.

      Das mit dem Definieren der POST Daten mache ich gerne.
      Denn es ist später einfacher die definierte $vari zu ändern, als die zigmalvorkommende $_POST. Ist aber letztenendes Geschmackssache (?)

      Kommentar


      • #4
        Also mal langsam, lies doch mal was ich dir schicke:
        mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
        mysql_real_escape_string() setzt einfach Backslashes vor bestimmte Zeichen, die beim Einfügen in SQL relevant sein könnten.

        PHP-Code:
        <?php
        echo "ich benutze ein Anführungszeichen innerhalb von Anführungszeichen so: \", ohne escapen geht das nicht";
        ?>
        Den Backslash \ vor zB " setzen nennt sich escapen. Damit wird dem " die eigentliche Funktion, nämlich den String zu beenden, genommen.

        Das SQL-Injection Beispiel von Wikipedia funktioniert im aktuellen PHP überhaupt nicht mehr, denn pro mysql_query() kannst du nur einen Query-Befehl ausführen.
        Also einen neuen Befehl kannst du nicht mehr einschleußen, es sei denn der Coder hat absoluten Blödsinn gebaut und der String läßt sich komplett über Eingabe-Parameter verändern (zB den SQL-Befehl per Parameter übergeben).

        Das Problem des Ausspähens von Daten mittels UNION oder der Manipulation der Restriktions-Bedingung (WHERE) bleibt, wenn du es erlaubst Strings in Felder zu übergeben, die Zahlen erwarten und deshalb nicht mit Anführungszeichen eingegrenzt sind. Beispiel aus Wikipedia:
        Aufruf:
        http://webserver/cgi-bin/find.cgi?ID=42+UNION+SELECT+login,+password,+'x'+F ROM+user
        Erzeugtes SQL:
        SELECT author, subjekt, text FROM artikel WHERE ID=42 UNION SELECT login, password, 'x' FROM user
        Wie du siehst ist 42 richtigerweise nicht in Anführungszeichen geschrieben (es ist ja eine Zahl und kein String), aber es wurde eben nicht geprüft, ob es sich auch um eine reine Zahl handelt - zB mittels is_numeric() oder die direkte Wandlung mit intval().

        Wenn du jetzt aber Anführungszeichen verwendest und der String nicht escaped wird, kann der "Hacker" dir Sonderzeichen unterjubeln, die deine String-Eingrenzung mittels ' beenden und dadurch das Statement verändern, zB die Bedingung beim Login.

        Code:
        SELECT * FROM users WHERE username = '$user' AND pw = '$pw'
        Wenn für
        Code:
        $user = admin' --
        eingegeben wird benötigt der Angreifer garkein Passwort mehr (-- ist die Kommentar-Funktion von SQL)
        Dann käme heraus:
        Code:
        SELECT * FROM users WHERE username = 'admin' -- 'AND pw = ''
        Escaped käme
        Code:
        SELECT * FROM users WHERE username = 'admin\' --' AND pw = ''
        heraus, also würde in der DB nach dem username "admin \' --" gesucht, den gibt es nicht, SQL-Injection gescheitert.


        http://de.wikipedia.org/wiki/Escape#...capen.E2.80.9C
        http://de.wikipedia.org/wiki/Escapen

        Kommentar


        • #5
          Klasse, danke und verstanden

          Du bist doch Moderator, ich hätte mal einen Vorschlag da es früher oder später eh jeden interessiert oder interessieren sollte.

          Eine Rubrik einzuführen:
          PHP - Sicherheit

          Dort kann man all diese Themen sammeln, oder aber z.B. wenn man eine grauenhafte Sicherheitslücke in einem geposteten Script entdeckt, dass dort entsprechend zu diskutieren, damit die PHP Gemeinde auch "lernt" sicher zu programmieren.... Denn das bringt uns oftmals in Verruf und schadet uns im allgemeinen langfristig....

          Fände ich ne gute Sache.

          Gruß, Micha

          Kommentar


          • #6
            Über die Forenaufteilung in andere Rubriken, statt Anfänger - Profis wurde schon einmal nachgedacht. Allerdings ist PHP-Sicherheit auch ein sehr allgemeines Thema. Aber vielleicht schaust du mal ins Tutorial-Forum, da ist zumindest ein ganz interessanter Beitrag von Basti:
            http://www.phpfriend.de/forum/ftopic51631.html
            Oder das Tutorial der PHP-Newsgroup:
            http://www.php-faq.de/ch/ch-security.html

            Kommentar

            Lädt...
            X