Juergen: von Formular ind MYSQL Datenbank

Ich habe nur eine Frage zum Thema sicherheit.

Bei einer Anfrage über ein Formular, wird ein Wort per POST an eine weitere Seite übergeben. Von dort aus soll es in der Datenbank eine Abfrage geben.

$sql =  "SELECT * FROM tabelle WHERE spalte='$_POST['formularwort']'";

sicherer wäre wohl

$_POST['formularwort'] = stripslashes($_POST['formularwort']); 
$_POST['formularwort'] = mysql_real_escape_string($_POST['formularwort']); 	

und dann

$sql =  "SELECT * FROM tabelle WHERE spalte='mysqli_real_escape_string($_POST['formularwort'])'";

oder geht es besser, einfacher, sicherer?

  1. Tach!

    Bei einer Anfrage über ein Formular, wird ein Wort per POST an eine weitere Seite übergeben. Von dort aus soll es in der Datenbank eine Abfrage geben.

    $sql =  "SELECT * FROM tabelle WHERE spalte='$_POST['formularwort']'";
    

    sicherer wäre wohl

    $_POST['formularwort'] = stripslashes($_POST['formularwort']); 
    $_POST['formularwort'] = mysql_real_escape_string($_POST['formularwort']); 	
    

    stripslashes() braucht man nicht mehr, weil das Feature namens Magic Quotes schon lange nicht mehr in PHP enthalten ist. Das mysql_real_escape_string() ist an der Stelle auch nicht sinnvoll. Innerhalb des Scripts möchte man mit dem Originalwert arbeiten und nur wenn es in eine bestimmte Ausgabe geht, muss man zu diesem Zeitpunkt und für diese Ausgabe spezifisch die Behandlung vornehmen. Abgesehen davon ist die mysql-ohne-i-Extension auch nicht mehr aktuell.

    und dann

    $sql =  "SELECT * FROM tabelle WHERE spalte='mysqli_real_escape_string($_POST['formularwort'])'";
    

    oder geht es besser, einfacher, sicherer?

    Nur das ist sinnvoll - wenn es syntaktisch richtig notiert wird.

    $sql =  "SELECT * FROM tabelle WHERE spalte='" .
        mysqli_real_escape_string($_POST['formularwort']). "'";
    

    oder mit Platzhaltern und sprintf(), damit der Statement-String nicht dauernd unterbrochen wird:

    $sql = sprintf("SELECT * FROM tabelle WHERE spalte='%s'",
        mysqli_real_escape_string($_POST['formularwort']));
    

    Zusätzlich gibt es noch Prepared Statements. Wenn die richtig angewendet werden, gehen die Daten einen eigenen Weg und müssen nicht so aufbereitet werden, dass sie sich korrekt in die Statement-Syntax einfügen lassen.

    Wir haben das Thema auch im Wiki aufbereitet: Kontextwechsel.

    dedlfix.

  2. Hallo Juergen,

    Ich habe nur eine Frage zum Thema sicherheit.

    Du solltest, wie dir hier irrc schon mehrfach geschrieben wurde, die mysql-Erweiterung nicht mehr verwenden.

    $_POST['formularwort'] = stripslashes($_POST['formularwort']); 
    $_POST['formularwort'] = mysql_real_escape_string($_POST['formularwort']); 	
    

    Das Umkopieren ist nicht erforderlich. Warum willst du die \ entfernen?

    $sql =  "SELECT * FROM tabelle WHERE spalte='mysqli_real_escape_string($_POST['formularwort'])'";
    

    Zwei mal real_escape_string ist nicht sinnvoll.

    oder geht es besser, einfacher, sicherer?

    Ja.

    Bis demnächst
    Matthias

    --
    Rosen sind rot.
    1. Tach!

      $_POST['formularwort'] = stripslashes($_POST['formularwort']); 
      $_POST['formularwort'] = mysql_real_escape_string($_POST['formularwort']); 	
      

      Das Umkopieren ist nicht erforderlich. Warum willst du die \ entfernen?

      Es ist hier kein Umkopieren (in eine zweite Variable mit einfacherem Namen). Es wird ja dieselbe Variable verwendet. Das könnte man also so machen, wenn es einen Grund gäbe, dass man die Eingabedaten bearbeiten muss. Beispielsweise, weil sie einem nicht direkt verarbeitbaren Format ankämen. Der Vorgang ist aber deshalb nicht erforderlich, weil es in dem Fall keinen technischen Grund gibt, die Daten an der Stelle zu verändern, besonders nicht in der gezeigten Weise.

      dedlfix.

  3. oder geht es besser, einfacher, sicherer

    Prepared Statements:

    $pdo = new PDO(...);
    $qry = $pdo->prepare('SELECT foo FROM bar WHERE name = ?');
    $qry->execute([$_GET['name']]);
    $foos = $qry->fetchAll();