Ankündigung

Einklappen
Keine Ankündigung bisher.

Nutzer-Eingaben: Sanieren und validieren (Best Practice)

Einklappen

Neue Werbung 2019

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

  • Nutzer-Eingaben: Sanieren und validieren (Best Practice)

    Um die übergebenen Werte z.B. eines Formulares, die per post gesendet wurden zu verwenden, sollten diese gesäubert werden, um mögliche Angriffe per XSS etc. zu verhindern. Zur Erhöhung der Sicherheit sollten diese Daten auch validiert werden, also z.B. ob eine Variable auch wirklich einen numerischen Wert darstellt und ob dieser im Gültigkeitsbereich liegt. So weit so gut.

    Bei meinen vielen Recherchen, auch aktueller Code-Beispiele, bin ich auf recht unterschiedliche und manche wohl eher überholte Methoden gestoßen, diese Aufgabe zu lösen.

    Meine Frage ist hier nach der "besten Praxis" (best practice).

    Vor einiger Zeit habe ich die Säuberung noch so gemacht, aber das ist wohl nicht mehr up-to-date:
    PHP-Code:
    if(isset($_GET)){
        
    clean_vars($_GET);
        
    $GET_CLEAN $_GET;
        
    //Speicher frei geben
        
    unset($_GET);
    }

    if(isset(
    $_POST)){
        
    clean_vars($_POST);
        
    $POST_CLEAN $_POST;
        
    //Speicher frei geben
        
    unset($_POST);
    }

    if(isset(
    $_SERVER)){
        
    clean_vars($_SERVER);
        
    $SERVER_CLEAN $_SERVER;
    }

    function 
    clean_vars(&$var){
        global 
    $globalConfig;

        if(
    $globalConfig['mainfile']!='administration'){
              if(
    is_string($var) ) {
                  
    $var htmlentities(strip_tags($var), ENT_QUOTES ENT_IGNORE"UTF-8");
              }else    {
                  if(
    is_array($var)){
                      foreach(
    $var as $key => $value)
                      
    clean_vars($var[$key]);
                  }
              }
        }

    Anschließend vor der Verwendung der jeweiligen Variable, diese noch validiert.

    Mein neuer Ansatz wäre nun per input_filter_array(). Allerdings ist mir auch nach dem "Studieren" einiger Beispiele nicht so recht klar, wie ich säubern und validieren zusammenbekomme und wie ich die Daten dann sinnvoll weiterverarbeiten kann, ohne einen zu großen Aufwand zu treiben.

  • #2
    Quoting betreibt man nur im HTML Output.

    Sanitizing ( nicht sanieren, säubern ) betreibt man beim Input Processing, aber nur dann wenn es notwendig ist das ein Input auf eine Vorgabe gefiltert werden soll.

    Validierung betreibt man immer beim Input damit (zusammengefasst) "man hat was man will".

    Das Datenbank minimal im Input-Processing ( könnte ) man auf 0-Byte-Sanitizing setzen.

    Sanitizing low-strip ( incl. 0-byte ):
    PHP-Code:
    $dbValue filter_input(INPUT_GET'something'FILTER_DEFAULTFILTER_FLAG_STRIP_LOW); 
    Validation
    PHP-Code:
    $dbValue filter_has_var(INPUT_GET'something')
       ? 
    filter_input(INPUT_GET'something')
       : 
    false

    Quoting
    PHP-Code:
    echo filter_var(
       
    $toOutput
       
    FILTER_SANITIZE_STRING
       
    FILTER_FLAG_ENCODE_LOW FILTER_FLAG_ENCODE_HIGH
    ); 
    Wichtig ist das du nicht einfach hingehst und pauschal "filterst", "sanitized" oder "quotest". Zumal das mitunter den Output / Input verfälscht und nicht auf jeden auflaufenden Fall definitiv zutreffen kann.
    [URL="https://gitter.im/php-de/chat?utm_source=share-link&utm_medium=link&utm_campaign=share-link"]PHP.de Gitter.im Chat[/URL] - [URL="https://raindrop.io/user/32178"]Meine öffentlichen Bookmarks[/URL] ← Ich habe dir geholfen ? [B][URL="https://www.amazon.de/gp/wishlist/348FHGUZWTNL0"]Beschenk mich[/URL][/B].

    Kommentar


    • #3
      Zitat von tr0y Beitrag anzeigen
      Wichtig ist das du nicht einfach hingehst und pauschal "filterst", "sanitized" oder "quotest". Zumal das mitunter den Output / Input verfälscht und nicht auf jeden auflaufenden Fall definitiv zutreffen kann.
      !

      Funktionen wie deine clean_vars() oder ähnliches zeigen eigentlich fast immer schon, dass das keine gute Idee ist. Wie man in tr0ys Beispiel sieht, ist das i.d.R. auch mit den PHP built-in-Funktionen nur ein einziger Aufruf, nur muss das eben je nach Kontext der richtige zu sein. Außerdem verleiten solche Funktionen oft zu einem falsches Sicherheitsgefühl.

      Ergänzend noch: $_GET, $_POST, $_SERVER etc. sind superglobale Arrays, darauf kann man von überall zugreifen. Auf deine "gefilterten" Variablen nicht. Das ist also auch nicht so eine clevere Idee.

      Kommentar


      • #4
        Danke für die Rückmeldungen!

        Doch ganz verstehen tue ich das noch nicht. Was kann daran falsch sein, die gesendeten Daten von potentiellen schädlichen Bestandteilen zu säuben (von mir aus mit filter_input() und in ein neues Array wie oben dargestellt z.B. $POST_CLEAN zu speichern und die entsprechende Superglobale also z.B. $_POST zu löschen. Auch wenn damit wahrscheinlich noch nicht alles getan ist und $POST_CLEAN natürlich keine Superglobale ist, könnte ich doch nun grundsätzlich auf $POST_CLEAN (etc.) zugreifen und übergebene Werte validieren:
        PHP-Code:
        $email filter_var($POST_CLEAN['email'], FILTER_VALIDATE_EMAIL)
            ? 
        $POST_CLEAN['email'
            : 
        false

        Übrigens ist mir die genaue Verwendung der Filter nicht klar, vor allem die Unterschiede der Flag Werte, da sich die Dokumentation darüber ausschweigt und ich auch keine andere erschöpfende Quelle gefunden habe.
        Wenn ich z.B. unter php.net nach FILTER_FLAG_STRIP_LOW suche erhalte ich:
        PHP Function List

        filter_flag_strip_low doesn't exist.
        Kennt jemand eine erschöpfende Quelle bzw. ein gutes Tutorial zum Thema?

        Kommentar


        • #5
          Die Dokumentation dazu ist leider wirklich sehr wenig ausführlich. Ich finde es deshalb schwierig, die eingebauten Filter zu verwenden. Gerade bei der Überprüfung von Nutzereingaben sollte man als Entwickler besser ganz genau wissen, was passiert.

          Wenn ich z.B. unter php.net nach FILTER_FLAG_STRIP_LOW suche erhalte ich:
          Da wird derzeit wohl nur die Liste der Funktionsnamen durchsucht, ja. Musst über eine allgemeine Suchmaschine gehen mit Zusatz von "site:php.net". So mache ich das zumindest immer.

          Hier findest du die grandiose Erklärung:

          Strips characters that has a numerical value <32.
          De facto scheint die Flag dafür zu sorgen, dass alle Bytes von 0x00 bis 0x1f aus der Eingabe entfernt werden.

          In dem entfernten Bereich liegen auch "\t", "\n" und "\r", was den Nutzen vielleicht etwas verringert.

          Was kann daran falsch sein, die gesendeten Daten von potentiellen schädlichen Bestandteilen zu säuben
          Zum Beispiel das Wörtchen „potenziell“. Wenn du etwa alle HTML-Tags immer aus allen GET- oder POST-Feldern entfernst, dann hast du ein Problem, wenn du doch mal HTML-Code zulassen möchtest (etwa für ein Admin-Backend oder weil die Daten in ein PDF gesetzt werden sollen, in dem HTML-Elemente gar keine besondere syntaktische Bedeutung haben). Du weißt so früh in der Ausführung noch gar nicht, was du mit den Daten am Ende anstellen möchtest. Deshalb ist es die sinnvollere Vorgehensweise, das für den jeweiligen Zielkontext (HTML, PDF, SQL, …) notwendige Escaping erst dann durchzuführen, wenn die Daten tatsächlich in den neuen Kontext überwechseln (also etwa in HTML-Code eingefügt werden).

          - http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel
          - http://wiki.selfhtml.org/wiki/Artike..._und_behandeln

          Es gibt wahrscheinlich gar keine Sanitizing-Operation, die immer für alle Eingaben anwendbar ist, denn prinzipiell spricht auch nichts dagegen, Binärdaten per GET oder POST zu versenden.

          Zitat von Tropi
          $_GET, $_POST, $_SERVER etc. sind superglobale Arrays, darauf kann man von überall zugreifen.
          Wobei das nicht unbedingt ein Vorteil sein muss. In Frameworks gibt es zum Beispiel häufig eine Request-Klasse, die die Werte verfügbar macht, um etwa diesen direkten Zugriff auf Superglobals zu vermeiden.

          Kommentar


          • #6
            Zitat von mermshaus Beitrag anzeigen
            Wobei das nicht unbedingt ein Vorteil sein muss. In Frameworks gibt es zum Beispiel häufig eine Request-Klasse, die die Werte verfügbar macht, um etwa diesen direkten Zugriff auf Superglobals zu vermeiden.
            Danke für den Hinweis. Ich seh zwar auch dort nicht den bahnbrechenden Vorteil davon, mein Hinweis ging allerdings mehr in die Richtung das es (eine Menge) zusätzliche Arbeit erfordert wenn man diese Variablen dann auch tatsächlich überall verfügbar machen will.

            Kommentar

            Lädt...
            X