Johannes: sichere Variable

Moin moin,

spricht eigentlich sicherheitstechnisch etwas dagegen, anstatt eine Nutzereingabe mit regulären Ausdrücken auf _erlaubte Zeichen_ hin zu prüfen, einfach die Variable mit $var = strip_tags(addslashes($_POST[var])) zu versehen und ohne weitere Prüfung zu verabreiten?

Ich habe eine Formular, wo eigentlich jede Eingabe erlaubt sein soll - außer eben Sachen, die böse sind. Die Eingaben werden in der DB gespeichert und später wieder am Bildschirm ausgegeben.

Wo ich bisher geschaut habe, gab's überall nur Erklärungen, wie und mit welchen Regex man auf erlaubte Zeichen prüfen kann, aber nirgends eine Antwort auf diese simple Frage. Sorry, wenn sie zu simpel sein sollte.

Johannes

  1. Hallo Freunde des gehobenen Forumsgenusses,

    Moin moin,

    spricht eigentlich sicherheitstechnisch etwas dagegen, anstatt eine Nutzereingabe mit regulären Ausdrücken auf _erlaubte Zeichen_ hin zu prüfen, einfach die Variable mit $var = strip_tags(addslashes($_POST[var])) zu versehen und ohne weitere Prüfung zu verabreiten?

    addslashes maskiert nicht alle Zeichen, die maskiert werden müssten.
    Verwende besser mysql_real_escape_string (bzw. die passende Funktion für dein RDBMS).

    Gruß
    Alexander Brock

    --
    SelfCode: ie:{ fl:( br:> va:) ls:[ fo:) rl:( n4:? ss:| de:> js:( ch:| sh:( mo:} zu:}
    http://againsttcpa.com
  2. Moin!

    spricht eigentlich sicherheitstechnisch etwas dagegen, anstatt eine Nutzereingabe mit regulären Ausdrücken auf _erlaubte Zeichen_ hin zu prüfen, einfach die Variable mit $var = strip_tags(addslashes($_POST[var])) zu versehen und ohne weitere Prüfung zu verabreiten?

    Da spricht ggf. sehr viel dagegen.

    Zunächst mal: _Wenn_ du addslashes und strip_tags verwendest, dann muß _zuerst_ strip_tags angewandt werden, um die unerwünschten HTML-Tags zu entfernen, und erst danach sollte der Reststring escapet werden.

    Zweitens: Verwemde addslashes() nur, wenn der Status von magic_quotes_gpc auf off ist, ansonsten hast du zweimal Escaping drin - und das sieht scheiße aus. :)

    Drittens: addslashes() ist nicht zum Escaping für Datenbanken geeignet. Nutze die Escape-Funktion der von dir benutzen Datenbank - im Fall von Mysql also mysql_real_escape_string(). Das bedeutet aber: Wenn magic_quotes_gpc=on, mußt du vorher alle Strings mit stripslashes() behandeln, ansonsten kriegst du auch wieder doppeltes Escaping.

    Viertens: Auf das Entfernen von HTML-Tags kann auch verzichtet werden. Es kommt drauf an, wie du die gesendeten Daten behandelst - und ausgibst! Wenn die eingegebenen Daten durchgehend nur als "Plain Text" betrachtet werden sollen, dann dürfen Zeichen wie "<" und ">" natürlich NICHT entfernt werden. Sie sollten auch ohne irgendein Escaping in der Datenbank abgespeichert werden. Und das wichtigste: Sie sollten entsprechend den Anforderungen der Ausgabe formatiert werden. Im Falle von simplem Text in HTML bedeutet das, dass ein "<" z.B. als Entity &lt; ausgegeben werden muß. Die Funktion htmlspecialchars() übernimmt das für dich. Dann erscheint jeder eingegebene Text 1:1 exakt wieder so auf der Webseite.

    Ich habe eine Formular, wo eigentlich jede Eingabe erlaubt sein soll - außer eben Sachen, die böse sind. Die Eingaben werden in der DB gespeichert und später wieder am Bildschirm ausgegeben.

    Plain Text ist nicht böse. Man muß ihn nur passend behandeln und darf ihn eben nicht zu wirksamem HTML werden lassen.

    Wo ich bisher geschaut habe, gab's überall nur Erklärungen, wie und mit welchen Regex man auf erlaubte Zeichen prüfen kann, aber nirgends eine Antwort auf diese simple Frage. Sorry, wenn sie zu simpel sein sollte.

    Die Eingabeprüfung mit regulären Ausdrücken ist für strengere Vorgaben sinnvoller. Und insbesondere reichen reguläre Ausdrücke bei HTML-Checks eventuell auch gar nicht aus. HTML ist eine Sprache, die man nicht vollständig mit RegEx erfassen und zerlegen kann - man muß sich eventuell einen Parser schreiben, der den Text (durchaus mithilfe von RegEx) passend "versteht".

    - Sven Rautenberg

    --
    My sssignature, my preciousssss!
    1. DANKE!

      Punkte 1 bis 4 habe ich nun verstanden, bisher kannte ich die Funktion mysql_real_escape_string() nicht.

      zu Punkt 4: Früher habe ich die Eingaben erst mit htmlspecialchars() umgewandelt und dann in der DB gespeichert. Problem dabei: Eine Vorschaufunktion mit z.B. substr($val, 0, 250) führt zu unschönen Ergebnissen, weil sie im ungünstigen Fall die Entities auseinanderreißt. Deshalb mache ich es jetzt umgekehrt, d.h. ich speichere die Daten so wie sie sind und formatiere sie dann bei der Ausgabe.

      Plain Text ist nicht böse. Man muß ihn nur passend behandeln und darf ihn eben nicht zu wirksamem HTML werden lassen.

      Demnach wäre ich also mit einem $val = mysql_real_escape_string(strip_tags(stripslashes($_POST["val"]))) auf der sicheren Seite.

      _
      Johannes

      1. echo $begrüßung;

        ich speichere die Daten so wie sie sind und formatiere sie dann bei der Ausgabe.

        Genauso ist es sinnvoll. Wenn du die Daten bereits für eine bestimmte Ausgabe maskiert in die Datenbank schreibst und später mal eine Ausgabe machen möchtest, die andere Maskierungen benötigt, dann wirst du zu der Erkenntnis kommen, dass das Mist war (bzw. zu der Erkenntnis bist du ja schon bei deinem Vorschau-Problem gekommen).

        Plain Text ist nicht böse. Man muß ihn nur passend behandeln und darf ihn eben nicht zu wirksamem HTML werden lassen.

        Demnach wäre ich also mit einem $val = mysql_real_escape_string(strip_tags(stripslashes($_POST["val"]))) auf der sicheren Seite.

        Jein. Wie Sven schon schrieb musst du zuerst auf an- oder ausgeschaltete Magic-Quotes testen und dementsprechend stripslashen. Es gibt zum Thema Magic Quotes ein Handbuch-Kapitel inklusive Anleitung zum Ausschalten/Entfernen der Maskierungen.

        echo "$verabschiedung $name";