SQL-Injections
Michi
- programmiertechnik
0 Robert Bienert0 Rouven0 Michi0 Robert Bienert0 Michi
0 dedlfix
Hallo,
von SQL-Injections gehört hab ich schon vor Jahren mal, in der Zwischenzeit aber nie was allzu sicherheitskritisches programmiert. Nun in letzter Zeit aber doch mal ein Login, die von mehreren Leuten genutzt werden, also hab ich mir mal angeschaut, was denn rauskommt, wenn ich z.B. mal ein "%"-Zeichen in ein Feld mit einbaue, das direkt so in der MySQL-WHERE-Klausel abgefragt wird:
Ich bekomme daraufhin die Servermeldung:
_____________________________________________________________________
Zugriff nicht möglich!
Der Server ist derzeit nicht in der Lage die Anfrage zu bearbeiten. Entweder ist der Server derzeit überlastet oder wegen Wartungsarbeiten nicht verfügbar. Bitte versuchen Sie es später wieder.
Sofern Sie dies für eine Fehlfunktion des Servers halten, informieren Sie bitte den Webmaster hierüber.
Error 503
_____________________________________________________________________
Geb ich eine Abfrageerweiterung mit Hochkommata ein, werden diese bei der Post-Übergabe gequotet. Dadurch scheint es so ohne Weiteres also auch nicht mehr möglich, was einzuschleußen.
Sobald mal keine Hochkommata nötig sind, z.B. bei Integervergleichen, schauts wohl wieder anders aus:
z.B. mal auf die natürlich gezielt zu Testzwecken gestaltete Klausel
"WHERE a="
hin den String
"1; DROP fuchsbau"
eingeben.
Sofern eine Tabelle fuchsbau besteht, sollte sie danach nicht mehr bestehen.
Meine Fragen dazu wären nun konkret:
1. Was steckt hinter dem Fehler 503 beim Eingeben des Prozentzeichens, den ich nur dann kriege, nicht jedoch, wenn ich die richtigen Daten (Name und Passwort) eingebe?
Dürfen Übergabeparameter einfach kein "%" enthalten?
2. Gibt es evtl. Standard-Kniffe (Funktions-Sammlung), die jegliche Einschleußattacken in jeglichen SQL-Dialekten außer Gefecht setzt?
(Hab ja keine Ahnung, was es sonst noch alles für Tricks gibt.
Hab mir z.B. mal Artikel wie diesen durchgelesen:
http://de.wikipedia.org/wiki/SQL_Injection)
Abdgedeckt sein sollten eben "%"-Eingaben, wenns nicht eh der Server schon blockiert, Hochkommata-Erweiterungen, falls solche per stripslashes() vom Code aus erlaubt werden, weitere angehängte SQL-Befehle nach einem Strichpunkt, besonders gefährlich scheinbar innerhalb von Integer-Abfragen, usw.
Gruß Michi
Moin!
- Was steckt hinter dem Fehler 503 beim Eingeben des Prozentzeichens, den ich nur dann kriege, nicht jedoch, wenn ich die richtigen Daten (Name und Passwort) eingebe?
<http://de.selfhtml.org/servercgi/server/httpstatuscodes.htm@title=HTTP 503> heißt, dass der Server momentan überlastet ist und deshalb nichts verarbeiten kann.
Dürfen Übergabeparameter einfach kein "%" enthalten?
Hast du das Prozentzeichen an die URL gehangen (GET) oder per POST übermittelt? Im ersten Fall ist das Prozent nämlich eine Art Escape-Sequenz.
- Gibt es evtl. Standard-Kniffe (Funktions-Sammlung), die jegliche Einschleußattacken in jeglichen SQL-Dialekten außer Gefecht setzt?
Jede SQL-API (MySQL, PostgreSQL, …) bietet dir eine Funktion, die häufig auf escape_string endet. Damit werden alle sensiblen Zeichen unschädlich gemacht. Ob auch % darunter fällt, weiß ich nicht, aber kommt das nicht eh nur bei LIKE zum Tragen?
(Hab mir z.B. mal Artikel wie diesen durchgelesen: http://de.wikipedia.org/wiki/SQL_Injection)
Das ist doch ein guter Anfang.
Abdgedeckt sein sollten eben "%"-Eingaben, wenns nicht eh der Server schon blockiert, Hochkommata-Erweiterungen, falls solche per stripslashes() vom Code aus erlaubt werden, weitere angehängte SQL-Befehle nach einem Strichpunkt, besonders gefährlich scheinbar innerhalb von Integer-Abfragen, usw.
Wieso unterscheidest du denn überhaupt zwischen „Integer-Abfragen“ und „String-Abfragen“? Zumindest in MySQL, vielleicht sogar laut SQL-Standard, ist auch das quoten einer Zahl erlaubt:
SELECT * FROM meiner_tabelle WHERE id='25'
Damit kannst sicherstellen, dass kein eingeschleuster SQL-Code ausgeführt wird.
Viele Grüße,
Robert
Hi,
Wieso unterscheidest du denn überhaupt zwischen „Integer-Abfragen“ und „String-Abfragen“? Zumindest in MySQL, vielleicht sogar laut SQL-Standard, ist auch das quoten einer Zahl erlaubt:
SELECT * FROM meiner_tabelle WHERE id='25'
was der Standard sagt - keine Ahnung. DB2 6-8 ist da sehr kritisch:
"Die Datentypen der Operanden für die Operation "=" sind nicht kompatibel."
Im Endeffekt verlangst du ja auch von der DB ein automatisches CASTEN von CHAR nach INT, eine überflüssige Operation.
MfG
Rouven
Moin!
Wieso unterscheidest du denn überhaupt zwischen „Integer-Abfragen“ und „String-Abfragen“? Zumindest in MySQL, vielleicht sogar laut SQL-Standard, ist auch das quoten einer Zahl erlaubt:
SELECT * FROM meiner_tabelle WHERE id='25'
was der Standard sagt - keine Ahnung. DB2 6-8 ist da sehr kritisch:
"Die Datentypen der Operanden für die Operation "=" sind nicht kompatibel."
Oha, das ist doch interessant.
Im Endeffekt verlangst du ja auch von der DB ein automatisches CASTEN von CHAR nach INT, eine überflüssige Operation.
Wenn ich auf Nr. Sicher gehen will, muss ich in meiner Anwendung von String nach INT casten, also gecastet wird auf jeden Fall. Und selbst SQL muss in beiden Fällen eine Typumwandlung durchführen, weil (im Beispiel) die 25 beides mal in einem String auftaucht.
Viele Grüße,
Robert
Hallo Robert,
- Was steckt hinter dem Fehler 503 beim Eingeben des Prozentzeichens, den ich nur dann kriege, nicht jedoch, wenn ich die richtigen Daten (Name und Passwort) eingebe?
<http://de.selfhtml.org/servercgi/server/httpstatuscodes.htm@title=HTTP 503> heißt, dass der Server momentan überlastet ist und deshalb nichts verarbeiten kann.
Dürfen Übergabeparameter einfach kein "%" enthalten?
Hast du das Prozentzeichen an die URL gehangen (GET) oder per POST übermittelt? Im ersten Fall ist das Prozent nämlich eine Art Escape-Sequenz.
Die Daten werden per Post übertragen. Ich bekomme diesen Fehler 503 aber auch nur, wenn ich so ein "%" über ein POST-Formularfeld übermittle, sonst nicht und zwar jeweils immer (d.h. ich krieg ihn stets, wenn ein "%" im POST-String enthalten ist und bei Eingabe eines normalen Strings nie). Von einer tatsächlichen Serverüberlastung kann man da wohl nicht ausgehen. Weiß nicht, wie ich das deuten soll...
Das "%" wäre vor allem für like-Abfragen interessant (zumindest fallen mir grad keine anderen ein), aber da darf bei einem Login natürlich nichts durchflutschen, insbesondere bei der Passwortabfrage nicht.
Gruß Michi
Moin!
Hast du das Prozentzeichen an die URL gehangen (GET) oder per POST übermittelt? Im ersten Fall ist das Prozent nämlich eine Art Escape-Sequenz.
Die Daten werden per Post übertragen. Ich bekomme diesen Fehler 503 aber auch nur, wenn ich so ein "%" über ein POST-Formularfeld übermittle, sonst nicht und zwar jeweils immer (d.h. ich krieg ihn stets, wenn ein "%" im POST-String enthalten ist und bei Eingabe eines normalen Strings nie).
Sehr merkwürdig. Was macht denn das entgegen nehmende Skript damit?
Von einer tatsächlichen Serverüberlastung kann man da wohl nicht ausgehen. Weiß nicht, wie ich das deuten soll...
Hast du mal mit top geschaut, was passiert, wenn du den Server fütterst? Vielleicht steigt der Resourcenverbrauch tatsächlich stark an.
Das "%" wäre vor allem für like-Abfragen interessant (zumindest fallen mir grad keine anderen ein), aber da darf bei einem Login natürlich nichts durchflutschen, insbesondere bei der Passwortabfrage nicht.
Deshalb gehört LIKE nicht zu einer Passwortabfrage. Ich habe bei PostgreSQL gerade herausgefunden, dass man % nicht so einfach escapen kann, ob \% wirklich hilft, weiß ich nicht genau.
Viele Grüße,
Robert
Hi Robert,
Das "%" wäre vor allem für like-Abfragen interessant (zumindest fallen mir grad keine anderen ein), aber da darf bei einem Login natürlich nichts durchflutschen, insbesondere bei der Passwortabfrage nicht.
Deshalb gehört LIKE nicht zu einer Passwortabfrage. Ich habe bei PostgreSQL gerade herausgefunden, dass man % nicht so einfach escapen kann, ob \% wirklich hilft, weiß ich nicht genau.
Klar, frag das Passwort üblicherweise auch nicht mit LIKE, sondern schön direkt über ein Gleichheitszeichen ab :), aber möglicherweise gibt es so exotische Fälle, an die man im Moment vielleicht gar nicht denkt, wo es eben mal sein kann, dass man einen String an irgendeiner sicherheitsrelevanten Stelle aus irgendwelchen Gründen über LIKE abfragen möchte, ohne jetzt gerade ein Beispiel zu wissen. Mir gehts hierbei sowohl ums Konkrete als auch ums Allgemeine. ;) Quasi der Leitgedanke bei der Sicherheitsverbesserung: Auch und gerade die schrägen kritischen Fälle zu finden, an die man zunächst nicht denkt. Da werd ich mir die nächsten Abende mal ein paar Tutorials reinleiern... Was den Servertraffic anbelangt, forsch ich auch mal nach.
Dank und Gruß!
Michi
echo $begrüßung;
z.B. mal auf die natürlich gezielt zu Testzwecken gestaltete Klausel
"WHERE a="
hin den String
"1; DROP fuchsbau"
eingeben.
Sofern eine Tabelle fuchsbau besteht, sollte sie danach nicht mehr bestehen.
Da fehlt noch, was geDROPt werden soll. Aber mal abgesehen davon ist es in aktuellen Systemen (MySQL+PHP) nicht möglich, mehrere Statements in einem Funktionsaufruf zu übergeben, wenn man dies nicht explizit erlaubt hat.
Abdgedeckt sein sollten eben "%"-Eingaben,
Arbeitet man mit LIKE und Benutzereingaben, so wird man sicherlich dem Benutzer nicht % und _ zumuten wollen sondern die eher gefälligeren * und ?. In dem Fall muss man diese beiden Zeichen sowieso nach % und _ übersetzen und kann dabei gleich noch % und _ maskieren.
echo "$verabschiedung $name";