Andi: sql injection verindern

Hallo zusammen,

Ich habe mich gerade mit oben genannten Thema beschäftigt, als ich mit erschrecken feststellen musste, das mehrere Webanwendung von mir nur unzureichend vor sql injection geschützt sind.
Teilweise werden Benutzereingaben die über $_POST oder $_GET kommen, direkt in die mysql Anweisung geschrieben.

Also habe ich mir folgendes überlegt:

  
foreach ($_POST as $key => $value){  
  $_POST[$key] = htmlspecialchars($value, ENT_QUOTES);  
}  
foreach ($_GET as $key => $value){  
  $_GET[$key] = htmlspecialchars($value, ENT_QUOTES);  
}  

Wird bei jedem Seitenaufruf als erstes aufgerufen.

Gibt es etwas gravierendes an dieser Vorgehenweise auszusetzen?

Gruß, Andi

  1. Lieber Andi,

    Gibt es etwas gravierendes an dieser Vorgehenweise auszusetzen?

    ja. Du enkodierst übermittelte Daten in ein Format, das nur in einem ganz bestimmten Kontext einen Sinn hat. Die Funktion htmlspecialchars enkodiert für den XML/HTML-Kontext. Aber Du willst ja die Daten nicht für den HTML-Kontext, sondern für den SQL-Kontext "entschärfen". Dafür bräuchtest Du eine andere Funktion.

    Es ist grundsätzlich besser, Daten erst an Ort und Stelle für den genau dort geltenden Kontext zu enkodieren. Siehe hierfür das SELFHTML-Wiki zu kontext-gerechtem Enkodieren.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hallo Felix,

      Da haben sich einige Lücken im Kopf gefüllt. Danke für den Link.

      Dann werde ich mich mal an die Arbeit machen und die entsprechenden Codeabschnitte raussuchen.
      Wäre ja auch zu einfach gewesen :)

      Vielen Dank und Grüsse,
      Andi

  2. Hi,

    foreach ($_POST as $key => $value){

    $_POST[$key] = htmlspecialchars($value, ENT_QUOTES);
    }
    foreach ($_GET as $key => $value){
      $_GET[$key] = htmlspecialchars($value, ENT_QUOTES);
    }

    
    >   
    > Wird bei jedem Seitenaufruf als erstes aufgerufen.  
    > Gibt es etwas gravierendes an dieser Vorgehenweise auszusetzen?  
      
    ja, einiges. Es lässt sich aber auf einen Nenner zusammenfassen: Unüberlegt.  
    Du gehst einfach über alle Eingabewerte und bereitest sie für eine Ausgabe als HTML auf, ohne zu überlegen, was \*wirklich\* damit passieren soll. Der Artikel über [Kontextwechsel](http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel) könnte eine wertvolle Lektüre für dich sein.  
      
    Faustregel: Daten werden \*dort\* maskiert oder codiert, wo sie in einen anderen Kontext gebracht werden, und dann spezifisch für \*diesen\* Zielkontext.  
      
    Ciao,  
     Martin  
    
    -- 
    "Hier steht, deutsche Wissenschaftler hätten es im Experiment geschafft, die Lichtgeschwindigkeit auf wenige Zentimeter pro Sekunde zu verringern." - "Toll. Steht da auch, wie sie es gemacht haben?" - "Sie haben den Lichtstrahl durch eine Behörde geleitet."  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
  3. hi zu später Stunde,

    foreach ($_POST as $key => $value){

    Alles in einem Aufwasch, nunja, das klappt nicht immer ;)
    Da ich auch grade am Aufräumen bin: Jeglicher SQL-Code fliegt raus aus meinen Scripten! Benutzereingaben werden an der Front vorgeprüft und wenn die in Richtung Datenbank gehen, laufen die über ein Objekt in eine Methode, kurzum, alle Datenbankzugriffe sind bei mir in Klassen organisiert, da wird das schön übersichtlich. In der entsprechenden Methode, wo ggf. noch andere Daten einlaufen, die nicht aus Benutzereingaben stammen, jedoch möglicherweise manipuliert werden können (Session-ID, URL...), erfolgt dann eine speziell auf den DB-Zugriff zugeschnittene Prüfung und die Methode gibt den Status zurück. Das vereinfacht auch die Fehlersuche ;)

    Hotti

    --
    Wir alle machen Fehler. Idealerweise da, wo sie auch gefunden werden.
  4. Hallo,

    Also habe ich mir folgendes überlegt:

    foreach ($_POST as $key => $value){
      $_POST[$key] = htmlspecialchars($value, ENT_QUOTES);
    }
    foreach ($_GET as $key => $value){
      $_GET[$key] = htmlspecialchars($value, ENT_QUOTES);
    }

    
    >   
      
    Da haben sich andere auch mal was überlegt und zwar schon vor dir. Das ganze schimpft sich Magic quotes und ist äußerst umstritten. Also falls du darauf noch mal stoßen solltest, lass dich gewannt sein und verwende es nicht.  
      
    Die richtige Vorgehensweise wurde dir ja schon in den anderen Posts nähergebracht.  
      
    Viele Grüße Novi
    
    -- 
    "(...) deshalb mag ich Binärtechnik. Da gibt es nur drei Zustände: High, Low und Kaputt." (Wau Holland)
    
  5. Hallo zusammen,

    Hallo,

    Teilweise werden Benutzereingaben die über $_POST oder $_GET kommen, direkt in die mysql Anweisung geschrieben.

    Du könntest prepare und bindParam von PDO verwenden.
    Damit brauchst Du Deine Daten nicht mehr zu maskieren und verhinderst gleichzeitig, dass Teile deiner Daten als SQL interpretiert werden.

    MAD

    1. Hi!

      Teilweise werden Benutzereingaben die über $_POST oder $_GET kommen, direkt in die mysql Anweisung geschrieben.
      Du könntest prepare und bindParam von PDO verwenden.

      Oder die Prepares Statements der mysqli-Extension. PDO lässt sich zwar in einigen Punkten angenehmer bedienen, mysqli ist aber "näher am Geschehen".

      Damit brauchst Du Deine Daten nicht mehr zu maskieren und verhinderst gleichzeitig, dass Teile deiner Daten als SQL interpretiert werden.

      Zumindest nicht mehr für SQL, die anderen Ausgabemedien müssen natürlich weiterhin berücksichtigt werden.

      @Andi: Wenn du schon dabei bist, deine Werke zu überarbeiten, schau gleich mit nach dem Thema Zeichenkodierung, damit das nicht auch dem Zufall überlassen ist.

      Lo!

      1. Hi!

        Hallo,

        Oder die Prepares Statements der mysqli-Extension. PDO lässt sich zwar in einigen Punkten angenehmer bedienen, mysqli ist aber "näher am Geschehen".

        Wenn es sich um MySQL handelt - was aus Andis Angaben nicht hervorgeht.

        Zumindest nicht mehr für SQL, die anderen Ausgabemedien müssen natürlich weiterhin berücksichtigt werden.

        Natürlich.

        MAD

        1. Hi!

          Oder die Prepares Statements der mysqli-Extension. PDO lässt sich zwar in einigen Punkten angenehmer bedienen, mysqli ist aber "näher am Geschehen".
          Wenn es sich um MySQL handelt - was aus Andis Angaben nicht hervorgeht.

          Doch, doch, in seinem zweiten Satz steht es.

          Lo!