Guma: Validierung von Formular-Feldern und Variablen

Hallo wie schon angesprochen mache ich gerade meine formulare SICHERER. Ganz sicher geht nicht, das ist mir jetzt klar. Aber etwas sicherer geht.

Mein erster Schritt heute:
Ich übernehme die Globalen Variablen aus dem Form. dazu habe ich zwei Überlegungen/Lösungen angestellt, die ich jetzt hier besprechen will:

Lösung 1:
if (! ($nid=$_GET['nid'])){$nid=NULL;}
$mynid ="$nid";
//reicht das aus?

Lösung 1: (Hier prüfe ich noch POST)
if (!empty($_GET[‘nid’])) //ist diese Abfrage genauer?
$mynid = $_GET[‘nid’];
else if (!empty($_POST[‘nid’]))
$mynid = $_POST[‘nid’];
else
$mynid = NULL;

So jetzt bin ich ja noch nicht sicher unterwegs, ich muss noch validieren um spammer besser abzuhalten.

Bei Nummerischen Daten habe ich es nicht zu schwer:

if (! ($nid=$_GET['nid'])){$nid=NULL;}
if $nid = (int) $nid;

//Frage: soll ich hier mit den variablen $nid prüfen:
if $nid = (int) $nid;
oder eher die Daten direkt prüfen:?
$_GET['nid'] = (int) $_GET['nid'];

Ist es notwendig auf nummeric zu prüfen oder ob so bei zahlen von 1 bis 10000?

Soweit bin ich jetzt - ich will noch versuchen zu prüfen ob eine Eingabe Zeilenumbrüche hat (für mail() attacken) und mysql_real_escape_string für SQL-Anweisung.

Grüße von Guma

  1. Gegen MySQL Injection nutze ich derzeit folgende Variablenprüfung:

    $myname = stripslashes($myname);
    $myname = mysql_real_escape_string($myname);

    Ist stripslashes denn nötig, wenn ich danach auch mysql_real_escape_string anwende?

    Grüße von Guma

    1. Meiner erste Fehlermeldung kommt gerade rein: mysql_real_escape_string(): Access denied for user: 'net777@localhost' (Using password: NO) in /home/www/net777/html/ghght/test.php on line 13

      dort steht:
      13 $myvorname = mysql_real_escape_string($myvorname);

      Was ist hier nicht richtig?

      1. hi,

        Meiner erste Fehlermeldung kommt gerade rein: mysql_real_escape_string(): Access denied for user: 'net777@localhost' (Using password: NO) in /home/www/net777/html/ghght/test.php on line 13

        dort steht:
        13 $myvorname = mysql_real_escape_string($myvorname);

        Was ist hier nicht richtig?

        Gumas Einstellung, zum wiederholten Male.

        Das Handbuch sagt mehr als eindeutig, dass diese Funktion eine bereits offene Verbindung erfordert - oder versucht, selbst eine herzustellen.

        Warum zum Geier liest du sowas nicht nach, bevor du fragst?

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Warum zum Geier liest du sowas nicht nach, bevor du fragst?

          hallo wahsager, achso eine verbindung zur datenbank also. verstehe. danke für die hilfe.

          guma

      2. echo $begrüßung;

        Was ist hier nicht richtig?

        Dein Verarbeitungsprinzip. Du versuchst noch während der Eingabedatenbehandlung selbige gleich für eine bestimmte Ausgabe vorzubereiten. Ordne deine Handlungen im Script den drei Prozessen Eingabe, Verarbeitung und Ausgabe zu und führe sie möglichst nacheinander und nicht gemischt aus.

        echo "$verabschiedung $name";

    2. hi,

      Gegen MySQL Injection nutze ich derzeit folgende Variablenprüfung:

      $myname = stripslashes($myname);
      $myname = mysql_real_escape_string($myname);

      Ist stripslashes denn nötig, wenn ich danach auch mysql_real_escape_string anwende?

      stripslashes ist genau dann nötig, wenn die vom Client übermittelten Daten vorher mit unnötigen Shlashes versehen wurden - wie es die Konfigurationsoption magic_quotes_gpc regelt, was man also vorher abfragt.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
  2. echo $begrüßung;

    Ich übernehme die Globalen Variablen aus dem Form. dazu habe ich zwei Überlegungen/Lösungen angestellt, die ich jetzt hier besprechen will:

    Übernehmen? Die Werte stehen doch schon für deinen Zugriff in den bekannten Arrays $_GET und $_POST. Du musst einfach nur darauf zugreifen. Umkopieren, "übernehmen", was auch immer ist nicht notwendig.

    if (! ($nid=$_GET['nid'])){$nid=NULL;}
    $mynid ="$nid";
    //reicht das aus?

    Wofür soll das ausreichen? Hast du bisher definiert, was in diesem speziellen Fall für dich "sicher" heißt?
    Möchtest du wissen, ob ein bestimmter Parameter übergeben wurde? Sieh nach, ob das zugehörige Array-Element in $_GET/$_POST gesetzt ist. isset() bietet sich dafür an.
    Einen Variablennamen in "" zu notieren ist in keinem Fall notwendig.

    Lösung 1: (Hier prüfe ich noch POST)
    if (!empty($_GET[‘nid’])) //ist diese Abfrage genauer?

    Für welches Ziel? Die Bedingung wird wahr, wenn $_GET['nid'] einen Wert enthält, den empty() nicht als leer ansieht. Ein String '0' beispielsweise wäre auch leer, obwohl er aus dem Zeichen '0' besteht.

    else if (!empty($_POST[‘nid’]))

    Du solltest dir im Klaren sein, über welchen Weg deine Werte zum Script finden. Alle beide Arrays ($_GET und $_POST) danach abzusuchen ist in den meisten Fällen unsinnig. Außerdem gibt es für den Fall $_REQUEST.

    //Frage: soll ich hier mit den variablen $nid prüfen:
    if $nid = (int) $nid;
    oder eher die Daten direkt prüfen:?
    $_GET['nid'] = (int) $_GET['nid'];

    Siehe oben. $nid anzulegen ist prinzipiell nicht notwendig. Nun kommt es auf den konkreten Anwendungsfall an, ob eine Variable für einen Zwischenschritt notwendig ist, oder ob man den Wert in $_GET/$_POST direkt einer Ausgabe oder einer Funktion, die den Wert für eine Ausgabe präpariert, übergibt, wenn keine weiteren Bearbeitungen mit dem Zwischenergebnis notwendig sind.

    Ist es notwendig auf nummeric zu prüfen oder ob so bei zahlen von 1 bis 10000?

    Das kommt auf deinen Anwendungsfall an. Welche Werte erwartest du? Prüfe auf diese Werte. Generell sind übrigens alle $_GET/$_POST-Werte vom Typ String.

    Soweit bin ich jetzt - ich will noch versuchen zu prüfen ob eine Eingabe Zeilenumbrüche hat (für mail() attacken) und mysql_real_escape_string für SQL-Anweisung.

    Das ist pauschal gesehen auch unsinnig. Wenn du einen Wert für einen Mail-Header erwartest, dann prüfe diesen auf Zeilenumbrüche oder erlaubte/verbotene Werte. Einem mehrzeiligen Kommentar die Zeilenumbrüche nicht zu gestatten wäre sicher nicht richtig. Und mysql_real_escape_string(), oder allgemein gesagt: Maskierfunktionen für bestimmte Kontexte, wendet man dann an, wenn man den Wert in den entsprechenden Kontext bringt, und nicht auf die Eingabewerte. Wenn später der Wunsch aufkommt, die Werte in einen anderen Kontext auszugeben ist es sicher ungünstig, wenn sie bereits für einen anderen Fall präpariert sind.

    echo "$verabschiedung $name";

    1. Danke für die Erläuterungen,

      Das ist pauschal gesehen auch unsinnig. Wenn du einen Wert für einen Mail-Header erwartest, dann prüfe diesen auf Zeilenumbrüche oder erlaubte/verbotene Werte.

      ich prüfe jetzt auf folgende worte in string um sql injections besser abzuwehren:

      $sql_alerts=array("select","delete","update","insert","into","drop","from","where","exec","SELECT","DELETE","UPDATE","INSERT","INTO","DROP","FROM","WHERE","EXEC");

      dann prüft strpos nach ob von den Worten etwas dabei ist, wenn ja --> dann exit().

      Wie prüfe ich jetzt auf Zeilenumbrüche in einem Wert für den Mail-Header? \n? oder?

      Grüße von Guma

      1. Hallo,
        die stripslashes wende ich jetzt so an:

        if (get_magic_quotes_gpc()) {
        $myemail = stripslashes($myemail);
        }

        wenn diese also 1 sind wird in diesem Fall stripslashes angewendet. So ist es doch schon besser! Oder?! Guma

      2. echo $begrüßung;

        ich prüfe jetzt auf folgende worte in string um sql injections besser abzuwehren:
        $sql_alerts=array("select","delete","update","insert","into","drop","from","where","exec","SELECT","DELETE","UPDATE","INSERT","INTO","DROP","FROM","WHERE","EXEC");

        Damit prüfst du nur einen Teil der möglichen SQL-Statements. Diese Prüfung würde ich so nicht vornehmen, sondern einfach nur dafür sorgen, dass die Eingabewerte nicht als Befehlsbestandteil angesehen werden können, sprich: richtig maskieren. Falls doch jemand eine SQL-Injection probiert, wird der zwar keinen Erfolg haben, ich aber nun unsinnige Daten in der DB. Doch unsinnige Daten bestehen ja nicht nur aus SQL-Statements. Wenn mir jemand Arbeit machen wollte, hat er noch viel mehr Möglichkeiten Unsinn einzugeben.

        Groß- und Kleinschreibung musst du nicht extra prüfen. Du müsstest dann noch auf viel mehr Schreibweisen testen, beispielsweise 'SeLeCt', 'SELect', usw. Es gibt die meisten Stringfunktionen auch in einer caseinsensitiven Version, zu erkennen meist an einem eingeschobenen i im Namen.

        Wie prüfe ich jetzt auf Zeilenumbrüche in einem Wert für den Mail-Header? \n? oder?

        Im Prinzip hat alles was einen ASCII-Wert kleiner als 32 hat, nichts in einem Wert verloren, den man in einen Mailheader einzufügen gedenkt.

        echo "$verabschiedung $name";

      3. hi,

        ich prüfe jetzt auf folgende worte in string um sql injections besser abzuwehren:

        So ein Blödsinn.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }