Lactrik: POST sicherer als GET?

Hallo :-)

Mal angenommen, ich habe eine Abstimmung... in einem Formular macht man gewisse Angaben, welche dann über POST übermittelt werden. Anschliessend wird ein Cookie gesetzt, dass Mehrfach-Abstimmung verhindert.

Als Beispiel nehmen wir mal eine Angabe, in der man nach Schulnoten bewerten muss... beim Ergebnis werden dann die Noten zusammengezählt und durch die Anzahl geteilt, wodurch sich die Durschnitts-Note ergibt. Dies könnte man für Bewertungen von irgendwas nutzen.

Hat man nun die Übermittlung per GET, dann steht doch in der Adresszeile, welche Note man gewählt hat... man könnte theoretisch die Zeile manipulieren und einfach einen Wert über 6 angeben, um den Schnitt anzuheben. (Nachdem man das Cookie für Mehrfach-Abstimmung gelöscht hat, natürlich)

Sogesehen ist POST doch sicherer oder nicht? Weil dort keine Manipulationen möglich sind?

Grüsse
Lactrik

  1. Hallo,

    Hat man nun die Übermittlung per GET, dann steht doch in der Adresszeile, welche Note man gewählt hat... man könnte theoretisch die Zeile manipulieren und einfach einen Wert über 6 angeben, um den Schnitt anzuheben. (Nachdem man das Cookie für Mehrfach-Abstimmung gelöscht hat, natürlich)

    Sogesehen ist POST doch sicherer oder nicht? Weil dort keine Manipulationen möglich sind?

    Nope - großer Irrtum: POST ist _genauso_ manipulierbar wie GET! Speichere doch mal das POST-Formular lokal ab, ändere das action-Attribut dass er auch garantiert auf dein Script auf dem Server zeigt, füge noch einen Auswahlpunkt für eine "Note 8" hinzu und schicke es ab. Der Aufwand ist größer, aber dennoch kein Hindernis!

    Grundsätzlich: Eingaben müssen _immer_ vom Bearbeitungsscript überprüft werden. Am Besten man lässt erst einen regulären Ausdrück à la preg_match ('/^'.$expression.'$/', $_POST['variable']); drüber los und dann prüft man noch, ob die Variable sich im gültigen Bereich befindet.

    Grüße,

    Christian

  2. Moin!

    Mal angenommen, ich habe eine Abstimmung... in einem Formular macht man gewisse Angaben, welche dann über POST übermittelt werden. Anschliessend wird ein Cookie gesetzt, dass Mehrfach-Abstimmung verhindert.

    Ich nehme grundsätzlich keine Cookies an - ich kann also mehrfach abstimmen... Von "verhindern" würde ich also nicht sprechen. Und wer rausfindet, was das Cookie macht, und es löscht, kann auch wieder abstimmen.

    Hat man nun die Übermittlung per GET, dann steht doch in der Adresszeile, welche Note man gewählt hat... man könnte theoretisch die Zeile manipulieren und einfach einen Wert über 6 angeben, um den Schnitt anzuheben. (Nachdem man das Cookie für Mehrfach-Abstimmung gelöscht hat, natürlich)

    Wenn dein Abstimmungsskript so doof ist, Werte außerhalb des erlaubten Bereichs zu verwenden, und nicht mit oder ohne Fehlermeldung zu verwerfen, dann bist du Schuld, nicht GET.

    Sogesehen ist POST doch sicherer oder nicht? Weil dort keine Manipulationen möglich sind?

    Man kann sich auch ein POST-Formular basteln, dessen Action auf dein Auswerteskript zeigt, und dann beliebige Fantasiewerte eintragen. Solange dein Skript nicht prüft, was da überhaupt ankommt, kann von Sicherheit absolut keine Rede sein!

    Dir muß eines klar sein: Daten vom Benutzer sind böse[tm]! Der Benutzer kann beliebige Daten senden, um Schaden anzurichten. Deine Formulare und festen URL-Parameter sind absolut kein Schutz vor bösen Daten - deine Skripte müssen dafür sorgen, dass sie nur erlaubte Werte weiterverarbeiten und definierte Aktionen ausführen. Erst dann ist etwas "sicher" - und die Methode GET oder POST ist vollkommen egal dafür.

    - Sven Rautenberg

  3. $boese_tm=0;

    [1] POST ist etwas sicherer als GET und zwar genau dann, wenn Du auch den Referrer prüfst.

    if ($HTTP_REFERER <> "Dein.Formular") {$boese_tm=1;}

    Und womöglich auch die Methode:

    if ($REQUEST_METHOD <> "POST") {$boese_tm=1;}

    [3] Die Eingabe prüfst Du serverserseitig:
     if ($Eingabe > 6) {$boese_tm=1;}
     if ($Eingabe < 1) {$boese_tm=1;}
     if (round($Eingabe) <> $Eingabe) {$boese_tm=1;}
     if ($boese_tm) { echo "Du böse!"; die() }
     else {
     #Deine Auswertung
     }

    :-)

    fastix

    1. $boese_tm=0;

      [1] POST ist etwas sicherer als GET und zwar genau dann, wenn Du auch den Referrer prüfst.

      Auch der REFERER ist beliebig manipulierbar.

      Andreas

      1. [1] POST ist etwas sicherer als GET und zwar genau dann, wenn Du auch den Referrer prüfst.

        Auch der REFERER ist beliebig manipulierbar.

        hallo!

        Deswegen steht dort: "etwas sicherer". Bei einem verbindungslosen Protokoll ist nichts(sic!) sicher!

        fastix

        1. Ach so:

          Referrer oder Referer: Da gab es doch irgendwo einen Schreibfehler.

          War es jetzt so, das HTTP_REFERER eigentlich (ortographisch korrekt) HTTP_REFFERER heißen müsste?

          Machen wir doch eine Abstimmung :)

          fastix

          1. Hallo,

            Referrer oder Referer: Da gab es doch irgendwo einen Schreibfehler.

            War es jetzt so, das HTTP_REFERER eigentlich (ortographisch korrekt) HTTP_REFFERER heißen müsste?

            Also: es heißt _referer_ - mit 3 r, 3 e und 1 f. Referrer (mit 4 r) oder refferer (mit 2 f) ist _falsch_ (im Computer-Kontext). Es gibt im englischen das Wort "referrer" (mit 4 r), aber ein "Rechtscreibfehler" ist in die HTTP-Spec gekommen und man will ja nicht 100000nde Browser/Server/CGI-Programme umstellen ;-)

            Mal kurz gegoogled und folgendes dazu gefunden:
            http://foldoc.linuxguruz.org//foldoc.php?referrer
            http://www.pigdog.org/auto/laughable_technology/shortfeature/944.html

            Grüße,

            Christian

            1. Ja, siehst Du: Und wenn Du wieder einen Rechtschreibfehler in meinen Beiträgen findest, dann darfst Du ihn getrost behalten :)

              Das gilt übrigens für jeden...

              fastix

              1. Hallo,

                Ja, siehst Du: Und wenn Du wieder einen Rechtschreibfehler in meinen Beiträgen findest, dann darfst Du ihn getrost behalten :)

                Hey - _Du_ hast doch angefangen, wolltest sogar eine Abstimmung :-)

                Grüße,

                Christian

          2. Hi,

            Referrer oder Referer: Da gab es doch irgendwo einen Schreibfehler.

            War es jetzt so, das HTTP_REFERER eigentlich (ortographisch korrekt) HTTP_REFFERER heißen müsste?

            orthographisch ;-)
               ^

            SCNR

            Der Rest (referer/referrer) wurde schon gesagt.

            Andreas

    2. Moin!

      $boese_tm=0;

      [1] POST ist etwas sicherer als GET und zwar genau dann, wenn Du auch den Referrer prüfst.

      Nein, auch bei GET kann man den Referrer prüfen! Das ist aber kein Sicherheitsgewinn, da man den Leerstring als Referrer auch zulassen muß - sonst kriegt man Probleme bei allen

      Ansonsten ist das, was du hier präsentierst, auch nicht gerade sicher programmiert.

      if ($HTTP_REFERER <> "Dein.Formular") {$boese_tm=1;}

      if (($_SERVER['HTTP_REFERER'] != "")&&($_SERVER['HTTP_REFERER'] != "formularurl") {$boese_tm=1;}

      Und womöglich auch die Methode:

      if ($REQUEST_METHOD <> "POST") {$boese_tm=1;}

      Entfällt, da $_POST ausgewertet wird...

      [3] Die Eingabe prüfst Du serverserseitig:
      if ($Eingabe > 6) {$boese_tm=1;}
      if ($Eingabe < 1) {$boese_tm=1;}

      if (($_POST['eingabe'] < 1)||($_POST['eingabe']>6)) {$boese_tm=1;}
      ...

      if (round($Eingabe) <> $Eingabe) {$boese_tm=1;}
      if ($boese_tm) { echo "Du böse!"; die() }
      else {
      #Deine Auswertung
      }

      - Sven Rautenberg

  4. Hi Lactrik,

    Mal angenommen, ich habe eine Abstimmung... in einem Formular macht man gewisse Angaben, welche dann über POST übermittelt werden. Anschliessend wird ein Cookie gesetzt, dass Mehrfach-Abstimmung verhindert.

    Das tut das Cookie mit sicherheit nicht, mehrfachabstimmungen verhindern. steht so auch in den anderen antworten.

    Sogesehen ist POST doch sicherer oder nicht? Weil dort keine Manipulationen möglich sind?

    Ich würde POST auch als etwas sicherer einstufen als GET, aber bei weitem nicht sicher. Eine Manipulation ist auch dort ohne grossen aufwand möglich. Sicher nur weil ich davon ausgehe das ein paar Benutzer weniger wissen was zu tun ist für eine Manipulation ;)

    Eines muss klar sein, 100% Sicherheit gibt es hier nicht. Aber durch eine gezielte Kombination von Sicherheitsmechanismen kannst du es sehr schwer und evtl sehr unattraktiv machen manipulieren zu wollen. Und die schliesst diejenigen aus die nicht das knowhow dazu haben.

    einige ideenansätze,

    • das Cookie ist nicht verkehrt, nur leicht umgehbar, aber du filterst mit sicherheit einige heraus.

    • REFERER, ist manipulierbar und nicht jeder Browser setzt einen, also prüfst du ob gesetzt und wenn ob der richtige, alles andere filterst du aus.

    • IPAdresse, hm, ist aber so ein kritischer punkt, nicht jeder hat eine "eigene" IP (z.B. Firmennetzwerk) und schon garnicht eine statische. Aber oft wird folgendes gemacht, die IP wird in eine Tabelle mit der Zeit eingetragen und bleibt dort 5min drin, erst danach kann wieder abgestimmt werden. Ist zwar keine sauberer lösung, aber ich denke effektiv, da diejenigen die mehrfachabstimmen wollen das sicherlich meist direkt hintereinander tun werden.

    • Eine Id für das Formular in ein hiddenfeld generiert, diese id als "schon abgestimmt" speichern, das formular dürfte in einigen Fällen aus dem cache und nicht vom Server kommen (musst du mit einigen massnamen "fördern").

    was mir gerade eingefallen ist, nur ideenansätze. Wichtig ist, je mehr Mechanismen um so sicherer, wobei man den user nicht kanns vergessen sollte, dumm ists dein Formular ist schon so "abgedichtet" das man nicht mal mehr ein einziges mal abstimmen kann ;)

    gruss

    Thorsten