Diskussion:SQL-Injection

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Produktlinks[Quelltext bearbeiten]

Wer kümmert sich um die Produktlinks und WP:WEB? In anderen Artikeln werden die konsequent gelöscht.

Warum mysql_real_escape_string bei $_POST Daten[Quelltext bearbeiten]

Hallo, Der Artikel im Abschnitt 3.4 beschreibt die verwendung von MYSQL_REAL_ESCAPE_STRING( string $unescaped_string [, resource $link_identifier] ) um eine Injection zu vermeiden.

Wenn ich allerding auf meinem Server Daten via Post übermittle, habe ich diese bereits escaped.

Würde ich also in einem Formularfeld mit dem Name 'suche' z.B. den Value mit ' OR = füllen und das via Submit abschicken, bekommt meine SQL Anfrage bereits SELECT * FROM table WHERE username LIKE '\' OR \'\'=\'\. Im Grunde geht er nicht aus dem LIKE Parameter raus.

Sind das vieleicht Einstellungen des Server, wenn ja welche? Wenn das keine Enstellung ist, wozu brauche ich dann für $_POST die Funktion MYSQL_REAL_ESCAPE_STRING.

Ergo wäre folgendes Beispiel doch doppelt gemoppelt, oder?

$abfrage = "SELECT spalte1 FROM tabelle WHERE spalte2 = '".mysql_real_escape_string($_POST['spalte2Wert'])."'"; $query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!");

--- Das escapen in deinem Fall ist durch die Konfig bedingt. Die php.ini kennt den Eintrag gpc_magic_quotes. Steht diese Option auf ON, werden die Werte escaped. Falls nicht, dann nicht. Thorny 10:28, 30. Jul. 2007 (CEST)

--- Vielen Dank für die Antwort -- Anonymously

--- Wobei anzumerken ist, dass magic_quotes* erstens in zukünftigen PHP-Versionen nicht mehr vorhanden sein wird und zudem den Zeichensatz garnicht in Betracht ziehen kann (genauso wie mysql_escape_string (ohne _real_)) und damit unter gewissen Umständen (Multibyte-Zeichensätze in MySQL) weiterhin SQL-Injections zulassen. Die richtige Lösung ist hier also weiterhin die Verwendung von mysql_real_escape_string (mit vorherigem Rückgängigmachen von magic_quotes_gpc). 84.148.185.141 20:35, 14. Jul. 2008 (CEST)

Gegenmaßnahmen[Quelltext bearbeiten]

  • Symbol support vote.svg Pro Gegenmaßnahmen sollten drinnen bleiben, sind zwar bei weitem nicht vollständig, geben aber erste Hilfestellungen

--Nochsoeiner 16:46, 20. Jun 2006 (CEST)

  • Bei den Gegenmaßnahmen ist ein Fehler drin - PLZ Daten sind keine Zahlen ! es kann durchaus PLZ geben die ein Buchstaben enthalten. Also bitte diese Sache raus da man hier sonst wieder Datenbankdesigner sieht die ihre PLZ als Integer setzen.

Lesenswert[Quelltext bearbeiten]

Gerade drüber gestolpert, sieht lesenswert aus, könnte aber auch zu kurz sein. --Flominator 20:29, 25. Jul 2005 (CEST)

Ist das ein "pro"? norro 20:48, 25. Jul 2005 (CEST)
  • Symbol support vote.svg Pro norro 20:48, 25. Jul 2005 (CEST)
  • Symbol neutral vote.svg Neutral Sehr schöne Beispiele, aber der einleitende Text gefällt mir nicht so, etwas kurz und sprachlich anstrengend. --Ixitixel 09:44, 27. Jul 2005 (CEST)
  • Symbol support vote.svg Pro Hab noch dranrumgebastelt, finde ich jetzt besser --Ixitixel 10:42, 28. Jul 2005 (CEST)
  • Symbol support vote.svg Pro Gefaellt mir gut, v.a. die praxisnahen Beispiele, die zur Erlaeuterung herangezogen werden sowie die Auflistung von adaequaten Gegenmassnahmen, die den Artikel vollstaendig machen. ---volty 21:04, 28. Jul 2005 (CEST)
  • Symbol support vote.svg Pro ---

Beispiel[Quelltext bearbeiten]

beispiel war fehlerhaft. 'x' ist viel zu umständlich. ein echter angreifer würde eine zahl verwenden. --LuckyStarr (in der Zusammenfassung)
Im Beispiel heißt die Spalte text. Ich vermute, dass es sich beim Datentyp daher eher nicht um eine Zahl handelt und damit ist das Beispiel mit der "1" ein Syntaxfehler. Ich weiß, dass es da draußen ein paar DBMSe gibt, die mit Datentypen auf Kriegsfuß stehen, aber der Artikel sollte nicht solche Bugs (Entschuldigung, laut MySQL ist das ein Feature) voraussetzen. --Hendrik Brummermann 07:54, 19. Aug 2005 (CEST)
Dann besser bitte auch die URL aus, die ist nämlich immer noch falsch! --LuckyStarr 19:57, 30. Aug 2005 (CEST)
Der Angreifer muss also bereits vor dem Angriff wissen, wie viele Spalten die ursprüngliche Abfrage hat. --LuckyStarr (im Artikel)
Ich denke, es ist Teil des Angriffs, das herauszufinden. --Hendrik Brummermann 07:54, 19. Aug 2005 (CEST)
Haarspalterei. --LuckyStarr 19:57, 30. Aug 2005 (CEST)

Escape-Zeichen[Quelltext bearbeiten]

Nur die wenigsten SQL-Dialekte kennen den Backslash als Escape-Zeichen. Oracle kennt z. B. nur die Möglichkeit, ein ' als ' ' zu escapen (von LIKE ... ESCAPE mal abgesehen).Udm 19:22, 7. Sep 2005 (CEST)

Das Beispiel bei "Datenbank Server verändern" hat einen Fehler[Quelltext bearbeiten]

da ich mir nicht 1000% sicher bin daß ich Recht habe und noch neu bin schreib ich das erst mal hier hin und schaue was passiert. Und zwar denke ich daß der Aufruf bei einer SQL Injection bei obigen Beispiel wie folgt lauten muss, da in URLs keine Leerzeichen verwendet werden dürfen: http://webserver/search.aspx?keyword=sql'%20GO%20EXEC%20cmdshell('format%20C')%20--

--Odigo 22:44, 3. Jan 2006 (CET)

stimmt, leerzeichen in URLs sind nicht erlaubt, auch wenn die meisten browser das (und mehr) anstandslos schlucken. "%20" geht, ist aber häßlich, dafür gibt es das "+". -- 22:54, 3. Jan 2006 (CET)
ja, ist definitiv schöner --Odigo 22:59, 3. Jan 2006 (CET)

MySQL Injection mit UNION[Quelltext bearbeiten]

Im Text steht: "Allerdings kann ein Angreifer das UNION-Schlüsselwort verwenden, um weitere SQL-Statements (bei MySQL sogar UPDATE und DELETE) einzuschleusen." Das mit dem kombinieren zweier SELECT-Anweisungen durch UNION kann ich nachvollziehen. Ein Anhängen eines UPDATE, oder DELETE Befehls per UNION an einen SELECT Befehl funktioniert jedoch bei mir (PHP 5 und MySQL 5) nicht. Ist das wirklich möglich?

---

So, ich habe gerade mal im Internet nachgeschaut. [1] UNION ist nur zum Verknüpfen von Anfragen (SELECT) da. Es vollkommener Schwachsinn, dass damit UPDATE bzw. DELETE Befehle eingeschleust werden können. In diesem Falle würde auch nur in einem Exploit-Code für z.B. phpBB ein Code existieren um die Adminrechte via. UNION zu ändern. FAZIT: Es geht nicht - ich entferne das eben.

Schutz vor Injections[Quelltext bearbeiten]

Sollte in dem Artikel nicht auch erklärt werden, wie ein Schutz gegen SQL-Injections funktioniert? Ich meine natürlich kein Tutorial oder so, aber zumindest eine kurze Beschreibung. --$traight-$hoota 11:21, 30. Apr 2006 (CEST)

War schon mal. Wurde aber vor einiger Zeit rausgelöscht, warum weiss ich nicht. hier in der Diskussion steht darüber nix. --82.135.113.226 17:50, 8. Mai 2006 (CEST)

Gegenmaßnahmen verbesserungswürdig[Quelltext bearbeiten]

Java-Sektion: Prepared Statements spielen ihren eigentlichen Performancegewinn nur aus, wenn man sie einmal definiert und mehrfach benutzt. Wird das nicht gemacht, gibts auch keinen echten Performancegewinn. PHP-Sektion: Das eigentliche Problem wird mit mysql_escape_string() oder mysql_real_escape_string() umfassend und abschließend gelöst. Die Funktion "quotesqlvar" ist nicht nur unnötig, sondern auch unklar definiert: Sie funktioniert nur für direkte Benutzereingaben. Für Werte, die aus anderen Quellen kommen (z.B. Dateien) liefert sie durch den Einbau der "magic-quotes"-Behandlung falsche Ergebnisse. Also: Am besten weg damit, Magic Quotes haben mit dem Problem nicht wirklich etwas zu tun. --Oimel 09:21, 7. Dez. 2006 (CET)


Es entsteht auch der falscher Eindruck der Sicherheit, das die beschriebenen Methoden aus dem Bereich Gegenmaßnahmen ausreichend sind. Es ist , zumindestens bei der Java (JDBC) Methode, nicht so das die Verwendung der prapereStatement-Methode ein Schutz bietet. Vielleicht frühe mal, aber in der derzeitigen Treiberversion von SUN eindeutig nicht. Ich denke das, um genügend Schutz zu bieten, die SQL Statements in dem Fall durch externe Bibliotheken oder Selbstgeschriebenes entsprechend bearbeitet werden sollen. --Kaster 10:22, 4. Jul. 2007 (CEST)

Prepared Statements spielen ihren eigentlichen Performancegewinn nur aus, wenn man sie einmal definiert und mehrfach benutzt.

Das ist so nicht richtig. In Oracle ist es egal ob man ein PS Objekt löscht oder nicht. Das Statement und der Plan (nicht das Ergebnis wohl gemerkt) ist im SharedPool und kann wieder verwendet werden.

oder Selbstgeschriebenes entsprechend bearbeitet werden sollen.

Ah ja und was schlägst Du da vor? Was hat sich an den JDBC Treiber von SUN verändert? Meines Wissens nach liefern die im JDK doch nur den JDBC:ODBC Treiber mit und alles andere kommt vom DB Hersteller? Also ich höre?


Prepared Statements sind Stored Procedures vorzuziehen, da i.d.R. nicht klar ist was letztere wirklich machen. Die Gefahr ist groß, dass sie doch wieder den SQL-Parser benutzen. Aber Prepared Statements sind auch nicht grundsätzlich sicher, wenn der Programmier z. B. diese zur Laufzeit zusammenbastelt und dabei auch Benutzereingaben verwendet. Sollte man irgendwie erwähnen ... -- 24. Nov. 2007, Circe

Ich trage jetzt mal nur ein, dass das mehrfache Benutzen von PreparedStatements einen Gewinn bringt. Wenn bestimmte Datenbanken DB-seitiges Caching von Ausführungsplänen unterstützen, möge das gerne (Quellenangabe?) jemand ergänzen. Andererseits gehört sowas primär in einen Artikel über Prepared Statements. --Leo141 12:45, 1. Okt. 2008 (CEST)

inhaltlich falsch[Quelltext bearbeiten]

Man kann mit php über mysql_query() immer nur ein Query senden, nicht mehrere. Alles ab dem Semikolon wird ignoriert.

.. was (Semikolon als Trennzeichen) eine Eigenschaft von MySQL ist und weniger von mysql_query(); 4.Feb. 08, Circe (Der vorstehende, nicht gemaess WP:SIG signierte Beitrag – siehe dazu Hilfe:Signatur – stammt von Circe (DiskussionBeiträge) 2:14, 4. Feb 2008)

Dementsprechend geht es auch nicht wenn ich:

.../sqltest.php?id=10;UPDATE+table+Set+testfeld=xxx+WH ERE+id=2

abfrage auf die php-Datei:

mysql_connect("localhost", "xyz","passwort") or die ("Datenbank derzeit nicht erreichbar");
mysql_select_db("usr") or die ("Datenbank derzeit nicht erreichbar");
$abfrage = "SELECT username FROM table WHERE id = '".$_POST["$id"]."'";
$query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!");  

Das Beispiel auf der Wikipediaseite ist also inhaltlich falsch und funktioniert nicht. (nicht signierter Beitrag von 91.12.220.125 (Diskussion) 21:17, 7. Jan 2008)

Oh Gott, unterschreibt doch bitte mit vier Tilden: --~~~~! --Rohieb 会話 +/- 21:17, 26. Feb. 2008 (CET)
Die Beispiele sind ja alle mit *.cgi und *.aspx in der URL, beziehen sich also sichtlich nicht auf die Funktion mysql_query() von PHP --Bernhard F. J. H. 19:05, 22. Feb. 2010 (CET)

injektion vs. injection[Quelltext bearbeiten]

gudn tach!
sql-injektion mit "k" scheint mir enorm unueblich zu sein. meines wissens benutzt man auch in der fachwelt fast nur die c-variante. die damalige aenderung von englisch nach deutsch wurde nicht weiter begruendet. was spricht gegen zurueckverschiebung? -- seth 15:32, 6. Apr. 2008 (CEST)

Die Hinverschiebung fand ich auch schon etwas komisch. IMHO spräche also nichts dagegen. --Rohieb 会話 +/- 18:00, 6. Apr. 2008 (CEST)
ok, bleibt noch die frage, ob mit oder ohne bindestrich. im englischen afais eher ohne. wuerde man es im deutschen eher mit schreiben? habe beides schon haeufig gesehen. -- seth 20:18, 6. Apr. 2008 (CEST)

Demonstration einer SQL Injection[Quelltext bearbeiten]

Also ich fand diesen Link doch sehr anschaulich, was sind denn Einwände dagegen? --Rohieb 会話 +/- 22:57, 9. Apr. 2008 (CEST)

404, verstehe. Kommentare in der Artikelzusammenfassung könnten manchmal helfen... --Rohieb 会話 +/- 22:58, 9. Apr. 2008 (CEST)

PDO-Beispiele[Quelltext bearbeiten]

Finde die PDO-Beispiele fast zu kompliziert, und dieses bind ist auch nicht unbedingt das Mittel der Wahl. Warum nicht die Version:

$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->execute(array("name", "wert"));

Das ist meiner Ansicht nach einfacher und praxisnäher. --Chricho 20:22, 26. Mai 2008 (CEST)

Anwendungsbeispiel[Quelltext bearbeiten]

Anwendungsbeispiel Elvis untot 09:28, 13. Aug. 2008 (CEST)

mysql_real_escape_string nutzt nichts bei Zahlen[Quelltext bearbeiten]

Vielleicht sollte irgendwie deutlicher gemacht werden, dass folgendes

$abfrage = "SELECT spalte1
            FROM tabelle
            WHERE spalte2 = '".mysql_real_escape_string($_POST['spalte2Wert'])."'";
$query = mysql_query($abfrage) or die("Datenbankabfrage ist fehlgeschlagen!");

nicht auf Abfragen bei Zahlen anzuwenden ist - sondern hier eine andere Prüfung benutzt werden muss.

Doch, das funktioniert auch mit Zahlen.
SELECT bla FROM tabelle WHERE spalte = '123'
Das ist gültiges MySQL, auch wenn spalte einen Zahlentyp hat. Es ist also tatsächlich nur EINE Methode des Variablen-Einsetzens in den MySQL-String notwendig.
85.177.223.203 13:19, 29. Nov. 2008 (CET)

source code[Quelltext bearbeiten]

Der Source code der cgi Datei wäre nett ich will das mal zuhause nachmachen (nicht signierter Beitrag von 78.48.209.160 (Diskussion | Beiträge) 20:10, 29. Jan. 2009 (CET))


Rechtliches[Quelltext bearbeiten]

weiß jemand wie es rechtlich damit aussieht? kann man für eine sql-injection belangt werden? oder ist das grauzone? irgendwelche informationen darüber? --91.97.240.111 11:20, 9. Feb. 2009 (CET)

Siehe Strafgesetzbuch: § 303a Datenveränderung; § 303b Computersabotage. Es kommt also IMHO wohl vor allem darauf an, ob etwas dabei kaputt geht. --BoMbY 21:57, 27. Jun. 2010 (CEST)
Dies alles und noch einiges mehr ist unter Computerkriminalität aufgeführt, IMHO reicht es aus, einfach darauf zu verlinken, anstatt bei jedem Werkzeug alle damit erdenklicherweise durchführbaren Delikte aufzulisten. --Leo141 12:38, 29. Jun. 2010 (CEST)
BoMbY, das ist zumindest jetzt mit §202c nicht mehr der Fall. Der Versuch und das finale Ausspähen ist bereits ein Straftatbestand.
Wenn z.B. mittels Log Dateien nachgewiesen werden kann (z.B. durch einen Gutachter), dass nicht nur ein Hochkomma zu Testzwecken eingefügt wurde, sondern ::: tatsächlich versucht wurde, Daten aus der Datenbank auszulesen, reicht das für den Straftatbestand "Versuch des Ausspähens von besonders geschützten Daten" in der ::: Regel aus. ITSecLion (Diskussion) 15:19, 2. Sep. 2014 (CEST)

Das ist ja nicht ganz richtig...[Quelltext bearbeiten]

Meine ich das nur oder ist der Satz unter "Siehe auch" inhaltlich falsch?

Cross-Site Scripting, ein Ansatz der Computerkriminalität, der Schwachstellen in Web-Browsern ausnutzt

Schwachstellen in der Webseitenprogrammierung oder dem Webserver, OK aber der Browser hat damit in der Regel nix am Hut...

Chaos 23:13, 21. Jun. 2011 (CEST)

Absolut richtig. Wobei ich überhaupt nicht verstehe, warum dort überhaupt auf Cross-Site Scripting verwiesen wird. Ich habe das durch einen Verweis auf Sicherheit_von_Webanwendungen#Angriffsmethoden ersetzt. ITSecLion (Diskussion) 15:13, 2. Sep. 2014 (CEST)

SQL-Einschleusung[Quelltext bearbeiten]

Spricht etwas gegen eine Verschiebung nach SQL-Einschleusung? Das ist, zumindest auf Deutsch, der gängige Begriff. Und dies ist ja die deutschsprachige Wikipedia. Ich schlage eine Verschiebung vor. 92.231.210.151 22:05, 13. Nov. 2011 (CET)

üblich ist der Begriff nicht, nur als Ergänzung/Erklärung zu "SQL-Injection". Der gägngige Begriff ist der englische. --Chire 14:27, 14. Nov. 2011 (CET)

PHP bzw. mysql_real_escape_string[Quelltext bearbeiten]

Gemäss http://ch2.php.net/manual/en/function.mysql-real-escape-string.php ist mysql_real_escape_string() veraltet. Was ist der Unterschied zur neuen Funktion mysqli_real_escape_string()? Im Artikel einfach ersetzen oder gibts da noch mehr dazu zu sagen?--Panda17 (Diskussion) 10:43, 5. Jul. 2013 (CEST)

Wie bereits von Panda17 erwähnt, sollte der Abschnitt zu PHP dringend überarbeitet werden, da die Funktion mysql_real_escape_string() in PHP7 gar nicht mehr enthalten ist. --MrKraut (Diskussion) 11:36, 5. Apr. 2016 (CEST)
Doch wurde ersetzt durch mysqli_real_escape_string() in PHP7. Die Dokumentation wurde entsprechend angepasst, wenn selbst MrKraut diese überlesen hat. mysqli.real-escape-string() --Ronny Witzgall (Diskussion) 19:33, 24. Mai 2017 (CEST)

Visual Basic (ADOdb)[Quelltext bearbeiten]

Das Beispiel hat bei mir unter VBA so nicht funktioniert. Folgendes geht:

  Dim cmd As ADODB.Command
  Set cmd = New ADODB.Command
  Set cmd.ActiveConnection = cn   ' Bestehende Verbindung zur Datenbank
  cmd.CommandType = adCmdText
  cmd.CommandText = "SELECT spalte1 FROM tabelle WHERE spalte2 = ?;"
  cmd.Parameters.Append cmd.CreateParameter(Type:=adVarChar, Direction:=adParamInput, Size:=25, Value:="Parameter Wert")
  Dim rs As ADODB.Recordset
  Set rs = cmd.Execute


Die im Artikel beschriebenen Attacken funktionieren im obigen Code nicht. Aber es gibt in den meisten Fällen auch keine Fehlermeldung. --88.205.103.241 14:22, 26. Okt. 2015 (CET)