muhertle: Query über url, Sicherheitslücke?

Hallo, angenommen ich übernehme bestimmte $_GET variablen direkt in eine  mysql Abfrage, kann man dann nicht die Url manuell so verändern, dass man irgendwelche befehle ausführen kann? z.b. dass man normal in der $query z.b. "....WHERE feld =".$_GET['bla'] stehen hat und jemand meint da noch irgendwie ein delete dranhängt, indem er die url bei &bla=hertle;DELETE usw... ich wills nicht machen, würd nur gern wissen obs geht

  1. Hallo muhertle!

    »»angenommen ich übernehme bestimmte $_GET variablen direkt in eine  mysql Abfrage, kann man dann nicht die Url manuell so verändern, dass man irgendwelche befehle ausführen kann?

    Natürlich.
    Siehe dclp FAQ: 16.18. Wie kann ich bösartigen Code in SQL-Abfragen unterbinden? und dclp FAQ: 12.11. Prüfe importierte Parameter. Traue niemandem.

    MfG
    Götz

    --
    Losung für Mittwoch, 16. März 2005
    Sie zogen Daniel aus der Grube heraus, und man fand keine Verletzung an ihm; denn er hatte seinem Gott vertraut. (Daniel 6,24)
    Jemand berichtete: Siehe, die Männer, die ihr ins Gefängnis geworfen habt, stehen im Tempel und lehren das Volk. (Apostelgeschichte 5,25)
    (Losungslink)
    1. Hallo!

      angenommen ich übernehme bestimmte $_GET variablen direkt in eine  mysql Abfrage, kann man dann nicht die Url manuell so verändern, dass man irgendwelche befehle ausführen kann?

      Natürlich.
      Siehe dclp FAQ: 16.18. Wie kann ich bösartigen Code in SQL-Abfragen unterbinden? und dclp FAQ: 12.11. Prüfe importierte Parameter. Traue niemandem.

      Jepp, und ich möchte auch noch http://de3.php.net/manual/de/security.database.php hinzufügen.

      Grüße
      Andreas

      --
      SELFHTML Tipps & Tricks: http://aktuell.de.selfhtml.org/tippstricks/
  2. Lieber muhertle!

    Es macht m.E. keinen wirklichen Unterschied,
    ob Du einen Querystring in der Adressleiste (GET) übergibst,
    oder mit dem Header übergibst (POST)

    Veränderbar ist es auf jeden fall.
    m.E. sind Sessions besser geeignet,  aber Sicherheit bietet
    das auch nicht unbedingt.
    Jedenfalls wäre es mal keine Plaintext Übertragung.

    Beste Grüße,
    Florian Langer

    1. Moin,

      Lieber muhertle!

      Es macht m.E. keinen wirklichen Unterschied,
      ob Du einen Querystring in der Adressleiste (GET) übergibst,
      oder mit dem Header übergibst (POST)

      Veränderbar ist es auf jeden fall.
      m.E. sind Sessions besser geeignet,  aber Sicherheit bietet
      das auch nicht unbedingt.
      Jedenfalls wäre es mal keine Plaintext Übertragung.

      Autsch...
      Vielleicht dann doch besser nicht antworten.
      Dein Wissen scheint um Sicherheit von Skripten scheint ausbaufähig.
      TomIRL

      1. Moin!

        Autsch...
        Vielleicht dann doch besser nicht antworten.
        Dein Wissen scheint um Sicherheit von Skripten scheint ausbaufähig.

        Wir alle hier lernen, indem wir Antworten schreiben, die gegebenenfalls durch bessere oder richtigere Lösungen oder Antworten korrigiert werden.

        Hinzugehen und eine Antwort als verbesserungswürdig zu kennzeichnen ist nur die halbe Arbeit. Der wichtigere Teil ist, eine bessere Lösung anzubieten oder die Fehler zu korrigieren, die gemacht wurden. Und der fehlt bei dir.

        • Sven Rautenberg
  3. Hallo,

    z.b. dass man normal in der $query z.b. "....WHERE feld =".$_GET['bla'] stehen hat und jemand meint da noch irgendwie ein delete dranhängt, indem er die url bei &bla=hertle;DELETE usw...

    Das geht so nicht. mysql_query() und andere derartige Funktionen akzeptieren nur *einen* SQL-Befehl pro Aufruf, d.h. ein ;DELETE ranzuhängen würde *nicht* funktionieren.

    Was jedoch funktionieren würde, wäre bla=25+OR+1, was dann in einem SELECT-Statement zu WHERE feld = 25 OR 1 würde, was dann zu WHERE 1 gekürzt werden könnte, d.h. die ganze Tabelle würde gelöscht werden.

    Deswegen ist es ganz wichtig, dass man a) alle SQL-Parameter in Anführungszeichen setzt, d.h. $select = "... WHERE feld = '" . $parameter . "'"; und b) diese Parameter auch richtig maskiert, d.h. $select = "... WHERE feld = '" . mysql_escape_string ($parameter) . "'"; [1]. Schlimmstenfalls wird dann feld mit irgend einem unsinnigen String verglichen - was dann zu gar keinem Ergebnis führt (aber auch nichts kaputt macht).

    Zu beachten ist hierbei auch die Einstellung magic_quotes_gpc, die dazu führt, dass auf *jegliche* Eingabe automatisch addslashes() angwendet wird. Damit soll Anfängern geholfen werden, damit diese eben sorglos "WHERE feld = '$bla'" schreiben können. Ich halte es jedoch für eine fatale Fehlentscheidung, dass magic_quotes_gpc eingebaut wurde, weil so Anfänger mit der Problematik nicht konfrontiert werden (da addslashes bei MySQL bei den meisten Zeichenketten vollkommen ausreicht), dass Parameter für die Datenbank maskiert werden müssen - was dann im schlimmsten dazu führt, dass sie sich über die Schrägstriche vor den Anführungszeichen aufregen, ein stripslashes überall reinmachen und am Ende die Scripte wieder nur so vor Sicherheitslücken strotzen. Ausserdem verlässt man sich so darauf, dass die Einstellung aktiv ist.

    Aus diesem Grund deaktiviere ich wenn möglich in der Konfiguration diese Einstellung bzw. sorge mittels eines kleinen Stück Codes dafür, dass _alle_ Daten egal mit welchen Servereinstellungen zwangsläufig *nicht* durch magic_quotes_gpc manipuliert wurden - dafür kümmere ich mich dann später beim Datenbankzugriff darum, dass alles korrekt maskiert wird. Da ich den Datenbankzugriff immer in eigene Funktionen/Klassen kapsele, gibt es immer eine einzige Datei bzw. immer nur eine Handvoll an Dateien, die _ausschließlich_ Datenbankabfragefunktionen enthalten, bei denen ich mich um das maskieren der Daten kümmern muss - so muss ich nur an einer Stelle kontrollieren, ob ich das überall richtig gemacht habe.

    Viele Grüße,
    Christian

    [1] Oder statt mysql_escape_string irgend etwas anderes entsprechendes.