Entwickler-Ecke

Datenbanken - SQL-Injections


olliterski - Fr 03.02.12 13:19
Titel: SQL-Injections
Moderiert von user profile iconMartok: Abgetrennt von [url=http://www.delphi-forum.de/viewtopic.php?t=106516]hier[/url]

Moin,

Parameter...ja ich stand auf der Leitung! ;)
Hatte auch das Prepare überlesen!

Aber mit den Injections würde ich dennoch die Kirche im Dorf lassen!
Oder gibt es in deinem Umfeld Patienten die so etwas, wie von dir skizziert, machen würden???

Selbst wenn Du 100.000 Dinge beim Import beachtest, wird es mit Sicherheit eine 100.001. Möglichkeit geben, wo etwas schief geht! ;)
Murphy´s Gesetz Nr. 3:

Hat man alle Möglichkeiten ausgeschlossen, bei denen etwas schief gehen kann, eröffnet sich sofort eine neue Möglichkeit! ;)


olliterski - Fr 03.02.12 16:20

user profile iconbaka0815 hat folgendes geschrieben Zum zitierten Posting springen:
... wenn da jetzt jemand - warum auch immer - den Eintrag "'; DROP DATABASE XYZ;" einfügen würde, würde er in deinem Fall die Datenbank droppen.


...was selbst bei deinem bisherigen Aufbau genau wie bei meinem Aufbau totaler Quatsch ist!

Wenn ich ein Statement zusammnbaue 'Insert into Table Values (' und dann '; DROP DATABASE XYZ;' einfüge und das SQL-Statment abschließe und gegen die DB fahre, erhalte ich einen Fehler über eine Anweisung die nicht ausgeführt werden kann nämlich das Insert vor dem Droppen!
In diesem Fall würde die Ausführung gestoppt werden!

Denn das Statement was die DB dann moniert lautet 'Insert into Table Values ('; DROP DATABASE XYZ;'!


baka0815 - Mi 08.02.12 12:45

Wenn du dein SQL wie folgt aufbaust:


Delphi-Quelltext
1:
SQL := 'INSERT INTO ' + Tabelle + ' (' + Spalten + ') VALUES (' + Werte + ')';                    


Und deine Datei "Tabelle.txt" wiefolgt aussieht:

Quelltext
1:
2:
3:
SpalteA  SpalteB
Wert1  Wert2
Wert3  Wert4


Wäre soweit erstmal alles in Ordnung und deine SQL-Anweisungen würden dann so aussehen:

SQL-Anweisung
1:
2:
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert1, Wert2);
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert3, Wert4);


Wenn nun jemand herkommt und die Datei wiefolgt ändert:

Quelltext
1:
2:
3:
4:
SpalteA  SpalteB
Wert1  Wert2
Wert3  Wert4
Wert5  Wert6); DROP DATABASE XYZ;


Dann sehen deine SQL-Anweisungen aufeinmal so aus:

SQL-Anweisung
1:
2:
3:
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert1, Wert2);
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert3, Wert4);
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert5, Wert6); DROP DATABASE XYZ;);


Gut, das ");" würde zu einem Fehler führen, aber das DROP DATABASE wäre zu dem Zeitpunkt ja bereits durch.


olliterski - Mi 08.02.12 13:20

user profile iconbaka0815 hat folgendes geschrieben Zum zitierten Posting springen:
Gut, das ");" würde zu einem Fehler führen, aber das DROP DATABASE wäre zu dem Zeitpunkt ja bereits durch.


Nicht wenn auf der DB bereits entsprechende Einstellungen vorgenommen wurden!


Martok - Mi 08.02.12 18:00

Oh, da möchte einer Suche bei Google SQL-INJECTION erklärt [http://xkcd.com/327/] haben :D

Übrigens ist in allen DBMS die ich kenne DROP DATABASE (genauso wie fast alle DDL) nicht Rollback-fähig.

Ein besserer Angriff wäre

Quelltext
1:
2:
3:
4:
SpalteA  SpalteB
Wert1  Wert2
Wert3  Wert4
Wert5  Wert6); DROP DATABASE XYZ;Select (1

Das ergibt

SQL-Anweisung
1:
2:
3:
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert1, Wert2);
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert3, Wert4);
INSERT INTO Tabelle (SpalteA, SpalteB) VALUES (Wert5, Wert6); DROP DATABASE XYZ;Select (1);
und ist damit syntaktisch korrekt.

user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
Dafür müsste derjenige der diesen Schaden verursachen wollte den Aufbau deiner Anwendung und damit die Abarbeitung innerhalb des Codes kennen und wisssen wann und wo er das Komma und die Klammer setzen muss!
Security by Obscurity... es gibt heute echt noch Leute, die ernsthaft daran glauben? Das erklärt einiges.

user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
Du eröffnest gerade nur eine neue (Schein)Möglichkeit - wenn das wirklich eintreten sollte, geh Lotto spielen! Denn wenn Du sowetwas voraussagen kannst bist Du schon nächste Woche Multi-Millionär!
Mit sowas wird man schon lange kein Millionär mehr. Jeder, der Pen-Testing macht wird das in den ersten 30 Sekunden probieren. Von denen 20 Sekunden vergehen bis sein Tool der Wahl gestartet ist.


Und weil zitate immer was schönes sind:
Terry Pratchett hat folgendes geschrieben:
Multiple exclamation marks are a sure sign of a diseased mind.



EDIT: das wichtigste vergessen: wenn wir das Thema "SQL-Injections" weiter diskutieren wollen, dann werde ich die Beiträge aus diesem Thema abtrennen und in ein neues verschieben. Nur so als Vorankündigung ;)


olliterski - Fr 10.02.12 15:31

Hallo Martok,

bakas Beispiel-Skript würde leider anders aussehen und normalerweise einen Fehler erzeugen.

Ich habe mir aber mal den Spass gemacht und mal eueren SQL-Gau auf meiner Datenbank versucht auszuführen. Habe leider einen Fehler erhalten und konnte das Skript nicht weiter ausführen.


Nersgatt - Fr 10.02.12 15:37

Nur, weil es gerade so schön dazu passt:
http://xkcd.com/327/


olliterski - Fr 10.02.12 15:38

... *lach*...naja! ;)


Martok - Fr 10.02.12 17:21

Was ist das für eine Datenbank? Und was für ein Tool, viele sind der Meinung Skripte nochmal verhackstücken zu müssen, bevor sie die an die DB schicken.

Grade auf MySQL 5.5 mit dem Query Browser getestet:

Skript Teil 1
1:
2:
3:
4:
5:
6:
7:
create schema "test";
use "test";
drop table if exists foo;
Create table foo (
  id int primary key auto_increment,
  wert int
);


Und jetzt importieren wir mal

Quelltext
1:
2:
3:
4:
5:
wert
100
200
300
400);drop database test;select(1



Skript Teil 2
1:
2:
3:
4:
insert into foo (wert) values (100);
insert into foo (wert) values (200);
insert into foo (wert) values (300);
insert into foo (wert) values (400);drop database test;select(1);

Und weg ist das Schema. Übrigens auch, wenn ich da noch ein "start transaction/rollback" drumrum wickle.

Vielleicht könntest du dein Beispiel ja nochmal mit einem Schema laufen lassen was du nicht wegzensieren musst? Ist immer doof, wenn grade der interessante Teil nicht da ist ;)


olliterski - Fr 10.02.12 17:56

...mytestdb...eine die ich zum testen generiert habe.
Die Tools werden von sybase mit ausgeliefert - SybaseCentral und ISQL.


baka0815 - Fr 10.02.12 19:26

Gerade mit einer MS-SQL 2008R2 getestet:

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
Create table foo (
  id int primary key identity,
  name varchar(100)
);

insert into foo (name) values (100);
insert into foo (name) values (200);
insert into foo (name) values (300);
insert into foo (name) values (400);drop database testdb;select(1);



Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)
Meldung 3702, Ebene 16, Status 3, Zeile 9
Die testdb-Datenbank kann nicht gelöscht werden, da sie zurzeit verwendet wird.

(1 Zeile(n) betroffen)


Er führt die Skripte also aus, kann die DB nur nicht droppen, da ich aktuell angemeldet bin.

Wenn wir das ganze jedoch leicht modifizieren:

SQL-Anweisung
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
use testdb;

Create table foo (
  id int primary key identity,
  name varchar(100)
);

insert into foo (name) values (100);
insert into foo (name) values (200);
insert into foo (name) values (300);
insert into foo (name) values (400);use master;drop database testdb;select(1);

use testdb;drop table foo;


Bekomme ich das folgende:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)

(1 Zeile(n) betroffen)
Meldung 911, Ebene 16, Status 1, Zeile 13
Die testdb-Datenbank ist nicht vorhanden. Stellen Sie sicher, dass der Name richtig eingegeben wurde.


Und meine Test-DB ist weg.


Martok - Fr 10.02.12 22:11

In Oracle ist das ja alles etwas anders, weil das Schema dem User gehört. Damit geht DROP SCHEMA nicht, aber DROP TABLE geht (aus dem gleichen Grund). Um das Schema loszuwerden, müsste man ein DROP USER absetzen, aber der User kann sich aus naheliegenden Gründen nicht selber löschen.

Vorgehen: User angelegt mit Rollen CONNECT, RESOURCE. Tabelle da rein, wie gehabt.

Wenn man das SQL als Skript ausführen lässt (was der einzige Weg ist, so ein Semikolon-getrenntes Zeugs ausgeführt zu bekommen), tut das exakt das was es auf allen DBMS auch tut und die Tabelle ist weg. Das komplette Schema kann man so abräumen, nur das Schema selbst nicht.

Bei Oracle gibt's noch einen anderen Vorteil für Parameter, das schreib ich gleich mal in den Ursprungsthread, denn da gehörts hin ;)


olliterski - So 12.02.12 00:46

Hallo,

1. Möglichkeit: User anlegen der nur einen Import fahren darf, also lesen von Dateien; Wäre für den direkten Import der Daten aus der Datei! Respektive einen der nur bestimmte Befehle ausführen darf.
2. Möglichkeit: Escapen! (Siehe hier [http://www.inside-php.de/tutorial/PHP-Sicherheit-13/SQL-Injections-vermeiden.html], hier [http://de.php.net/manual/de/security.database.sql-injection.php] oder eins davon [http://www.google.de/search?client=opera&rls=de&q=datenbank+drop+unterbinden+verbieten&sourceid=opera&ie=utf-8&oe=utf-8&channel=suggest])
3. Möglichkeit: (trifft speziell auf Oracle zu!) per Trigger ausschließen

Was die Oracle DBs angeht hab ich jedenfalls ne Fehlermeldung.


Martok - So 12.02.12 05:45

Das war doch grade der Punkt der Diskussion: sowas ist einfach zu vermeiden, wenn man Parameter verwendet (und schneller in der Ausführung ist es auch) :roll:

Dass man seine Rechtevergabe immer durchdenken sollte ist eh klar (hoffe ich), aber grade das oft verwendetet 1-User-Pro-Application macht das etwas schwierig. Da muss der User ja wenigstens DELETE können, und damit geht im Zweifelsfall immer noch ein DELETE FROM xyz;.

DROP DATABASE ist ja hier auch das Maximalbeispiel, etwas Abstraktionsvermögen erwarte ich von einem Programmierer dann schon. Wenn ich beliebiges SQL ausführen kann, ist "löschen" ja meistens auch nicht das cleverste. Ich könnte Daten modifizieren, klauen, proceduren installieren.

Aus Gründen der Defense in Depth ist es sicherlich gut, das auf der DB auch noch mal zu verriegeln. Aber gar nicht erst ein Scheunentor offen zu haben ist immer die bessere Lösung. Man muss es ja nicht zu einfach machen.


olliterski - So 12.02.12 12:02

...ok, sehe ich ein - und wie schließt man es nun deines Erachtens nach?

(war ja glaube ich bakas Hauptanliegen)


Xion - So 12.02.12 12:28

user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
....was mich wieder in einer anderen meiner Aussagen bestätigt - auf einer richtig eingestellten Datenbank ist ein Droppen der DB per SQL-Injection NICHT MÖGLICH!

Wie Martok schon sagte, wer will den schon die Datenbank droppen (für sowas gibts ja Backups)? Eigentlich ist es viel interessanter, die Daten auszulesen oder zu modifizieren. Wenn du das auch verbietest, dann kann man nichtmehr auf die Datenbank zugreifen.
User-Rechte bringen dir da herzlich wenig, da du ja per Injection die Rechte von dem Ausführenden nutzt.

user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
Egal ob man mit Triggern arbeitet, den SQL-String vorher durch escaped oder einfach nur einen speziellen User auf der DB verwendet der einige Befehle eben NICHT ausführen darf - das sind alles Einstellungen die auf der DB gemacht werden müssen und nicht im Programmcode!.

Die Datenbank weiß aber NICHT, ob da wirklich der richtige Nutzer davor sitzt oder sich wer dort eingeschlichen hat. Ja, mit Triggern kann ich verhindern, dass z.B. der Preis von ner Tüte Gummibärchen im Webshop über 10 liegt. Dann setzt ich ihn per Injection eben auf 0 und kaufe gleich mal 1000 Stück ;) Nur so als Beispiel. Ok, das kann man auch per Trigger verhindern, aber dem Hacker wird schon was einfallen. Die Initiative liegt immer beim Angreifer, erst danach weißt du, was du vergessen hast.

PS: Ich finde es faszinierend wie sachlich hier auf provozierende Kommentare geantwortet wird :zustimm:

Weiß nicht ob das schonmal verlinkt wurde: http://www.unixwiz.net/techtips/sql-injection.html
Besonders das mit der Email find ich ne coole Idee :P


BenBE - So 12.02.12 14:32

@Martok: Man kann in mindestens einem DBMS das DELETE auch zeitbasiert limitieren. Ist zwar dann ärgerlich, wenn gerade der Admin aus der User-Tabelle fehlt, die User aber noch da sind, aber immer noch besser als die gesamte User-Basis weg :P Und dabei denke ich gerade an MySQL ...

Ach ja und zu
user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
....was mich wieder in einer anderen meiner Aussagen bestätigt - auf einer richtig eingestellten Datenbank ist ein Droppen der DB per SQL-Injection NICHT MÖGLICH!

Auf einer vernünftig genutzten DB, sind SQL-Injektions nicht möglich. Wenn ich SQL injekten kann, ist deine Security in der Regel gebrochen; .. Die Auswirkungen verhindern zu wollen, ist so ähnlich wie im Auto die Handbremse anzuziehen, damit man nicht mit 200 gegen die nächste Allee-Bepflanzung rast.

user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
Daher auch meine Aussage, dass an der einen oder anderen Stelle einfach nur Szenarien konstruiert wurden, die eher unwahrscheinlich sind!

Ich merk dich mal eben grad bei mir mit nem Kreuz vor ... Und nicht jammern, wenn mal eine DB von Dir gehackt wird ... Security fängt VOR dem Scheunentor an.


olliterski - So 12.02.12 23:29

....stimmt.


Tranx - Mo 13.02.12 05:52

Gut, dass niemand weiß, dass ich Rumpelstilzchen heiß.

Mensch, ich bin froh, dass ich in meinem überschaubaren Anwendungsrahmen der Datenbank darüber nicht im Ansatz nachdenke, irgendwas in irgendwas zu injizieren. Also ganz ehrlich Leute. Ich verstehe mal wieder nur 1% von dem, was da steht, denn die Begriffe sagen mir schlichtweg nichts, wenn Bebe z.B. schreibt:

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
@Martok: Man kann in mindestens einem DBMS das DELETE auch zeitbasiert limitieren. Ist zwar dann ärgerlich, wenn gerade der Admin aus der User-Tabelle fehlt, die User aber noch da sind, aber immer noch besser als die gesamte User-Basis weg :P Und dabei denke ich gerade an MySQL ...


user profile iconolliterski hat folgendes geschrieben Zum zitierten Posting springen:
....was mich wieder in einer anderen meiner Aussagen bestätigt - auf einer richtig eingestellten Datenbank ist ein Droppen der DB per SQL-Injection NICHT MÖGLICH!Auf einer vernünftig genutzten DB, sind SQL-Injektions nicht möglich. Wenn ich SQL injekten kann, ist deine Security in der Regel gebrochen; .. Die Auswirkungen verhindern zu wollen, ist so ähnlich wie im Auto die Handbremse anzuziehen, damit man nicht mit 200 gegen die nächste Allee-Bepflanzung rast.


Das Einzige, was ich aus diesen Angaben erlesen kann, ist, dass Sicherheit (warum das Wort Security?, ist das sicherer?) wie immer umgangen werden kann. Wenn man nur weiß, wie. Aber mit Einflechten von Begriffen wie "Injection", DBMS (Datenbankmanagementsystem???), Droppen, zeitbasiert limitieren (heißt für mich zeitlich begrenzen, was auch immer das heißen soll) werden Leute bloß verunsichert. Mit Sicherheit hat das wenig zu tun.

Tut mir Leid, das hier mal zu schreiben.

Und wenn ich mich hiermit als totaler Laie und tumber Vollidiot, was Datenbankanwendungen anbelangt, präsentiert habe, so ist mir das aber auch sowas von egal! Das glaubt ihr kaum. Und es geht mir auch nicht um ein korrektes Deutsch, gleichsam neonazistische Ablehnung sämtlicher Fremdwörter. Es geht mir um eine sinnvolle Verwendung derselben. Gerade im IT/Programmierbereich wuchern diese in einer weise, dass ich schon kaum mehr Lust habe, irgendwelche Artikel oder Beiträge zu lesen, weil mit solchen Satzkonstruktionen, wie oben zitiert, nichts anfangen kann. (Ich setze mal das Kürzel IT als bekannt voraus) ;)


Xion - Mo 13.02.12 13:27

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
warum das Wort Security?, ist das sicherer?

Es gibt da einen kleinen Unterschied zwischen Sicherheit (Security) und Sicherheit (Safety). Letzteres ist die Sicherheit VOR der Software, dass der Kessel nicht explodiert aufgrund eines Bugs. Security ist aber, dass die Software geschützt wird (z.B. vor dem explodierenden Kessel :mrgreen: ).

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Aber mit Einflechten von Begriffen wie "Injection"

Hmm, naja, das ist halt ein Fachbegriff. Es heißt nunmal SQL-Injection, kannst es auch gerne SQL-Injektion nennen :D

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
DBMS (Datenbankmanagementsystem???)

Also das kann man schon vorraussetzen. Gemeint ist damit z.B. MySQL, also die ganze Software, um die Daten auf die/von der Platte zu holen und die SQL-Anfrage zu beantworten.

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Droppen

den "DROP" SQL-Befehl nutzen ;) Das bezieht sich auf weiter oben, wo es genau darum ging.

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
werden Leute bloß verunsichert. Mit Sicherheit hat das wenig zu tun.

Hmm, naja. Irgendwie muss man ja das Ausdrücken was man meint. Wenn mans nicht versteht, muss man einfach nochmal nachfragen, dann wirds sicher auch nochmal ohne diese Begriffe erklärt :)

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Und wenn ich mich hiermit als totaler Laie und tumber Vollidiot, was Datenbankanwendungen anbelangt, präsentiert habe, so ist mir das aber auch sowas von egal!

Das ist die richtige Einstellung :)
Das Problem ist denke ich, dass hier Leute, die jeden Tag mit Datenbanken zu tun haben und Leute, die noch nie was damit gemacht haben, aufeinandertreffen.

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Es geht mir um eine sinnvolle Verwendung derselben. Gerade im IT/Programmierbereich wuchern diese in einer weise, dass ich schon kaum mehr Lust habe, irgendwelche Artikel oder Beiträge zu lesen, weil mit solchen Satzkonstruktionen, wie oben zitiert, nichts anfangen kann.

Ja, das gibts natürlich auch. Wenn man wichtig klingen will, der Inhalt aber nicht so toll ist, dann muss man soviele Fremdwörter reinpacken dass niemand mehr durchblickt.