# Eingaben auf SQL Befehle überprüfen



## Meldanor (22. Okt 2009)

Hiho,

eventuel kennt einer das Problem: xkcd Comic
Man hat ein GUI geschrieben für User(z.B. Schüler) und in dem Moment, wo ein Textfeld vorhanden ist, besteht die Gefahr, dass er Datenbankcode mitschickt, wie in dem Bespiel beschrieben.
Gibt es eine Möglichkeit dies zu verhindern, ohne dass ich den Text auslesen muss und dann auf Kernwörter wie SELECT, UPDATE, DELETE etc. überprüfen muss?

Mfg
mel


----------



## tfa (22. Okt 2009)

Ja. Benutze ausschließlich Prepared Statements und kein dynamisch zusammengebasteltes SQL.
Wenn du ein ORM-Framework wie Hibernate benutzt, musst du dich nichtmal darum kümmern.


----------



## Meldanor (22. Okt 2009)

Hab jetzt mal schnell drüber gelesen und auf grund dessen, dass das Prepared Statement schon compiliert ist, bevor es abgeschickt wird, kann ich auch kein "; INSERT INTO .... " mehr einfügen und so ein neues Statement aufmachen?
Würde Java meckern oder die Datenbank(in dem Fall mySQL Server 5.1)?


----------



## Michael... (23. Okt 2009)

Meldanor hat gesagt.:


> kann ich auch kein "; INSERT INTO .... " mehr einfügen und so ein neues Statement aufmachen?


Was wird den ins Textfeld eingegeben? PreparedStatements kann man so vorbereiten, dass man beliebige Select, Insert, Update, Delete, ... Statments parametrisiert auf der Datenbank ausführen kann.


----------



## Meldanor (23. Okt 2009)

Ich hab eine Datenbank und ein Programm, was zur Katalogisierung von Medien ist.
Nehmen wir am besten Bücher:
Da kann ich einen Titel, eine ISBN, einen Autor und ne Seitenanzahl eingeben.
Wenn ein User ein neues Buch eingibt, hat er halt 4 Textfelder, für jedes Attribut eines.
und da könnte er halt Fremdcode mit einschleusen.
Aber wenn ihr sagt, dass ein PreparedStatement ein bereits compiliertes Statement ist, wo noch ein Paramater rangehangen wird, bevor es ausgeführt wird, dann kann ich ja kein neues Statement aufmachen mit INSERT .. ;


----------



## ARadauer (23. Okt 2009)

> Würde Java meckern oder die Datenbank(in dem Fall mySQL Server 5.1)?


Niemand würde meckern, die vom Benutzer eingegebenen Injection würde einfach als Wert eingefügt und nicht ausgeführt...



> dann kann ich ja kein neues Statement aufmachen mit INSERT .. ;


wieso nicht? was meinst du mit aufmachen?


----------



## Michael... (23. Okt 2009)

Du musst ja kein neues Statement erzeugen, das ist ja der Witz an den PreparedStatements
Bsp - ist jetzt ohne Fehlerüberprüfung so dahingeschrieben

```
PreparedStatement ps = myConnection.prepareStatement("Insert into Buechertabelle (isbn, titel, autor) values (?, ? ,?)");
ps.setString(1, "1234567");
ps.setString(2, "Mein Buch");
ps.setString(3, "Mein Name");
ps.execute();
```


----------



## Meldanor (23. Okt 2009)

Michael... hat gesagt.:


> Du musst ja kein neues Statement erzeugen, das ist ja der Witz an den PreparedStatements
> Bsp - ist jetzt ohne Fehlerüberprüfung so dahingeschrieben
> 
> ```
> ...



Okay, ich habe mich mit Statement falsch ausgedrückt.
Ich meinte mit Statement einen neuen MySQL Befehl erstelln.

Wir haben ja

```
INSERT INTO bucherTabelle(isbn,titla,autor) VALUE (?,?,?);
```

wenn ich jetzt das preparedStatement habe und dann mit ps.setString(1, textField.getText()); den Paramater für ISBN setze, ist es dann ausgeschlossen, dass ein neuer MySQL Befehl mit eingeschleust wird? So dass kein "böser Mensch" statt einer ISBN 3-978-54545-12 einfach

```
DROP buecherTabelle;
```
schreiben kann und mir so die Datenbank zerschießen kann?

Und hier ist die Frage: Was würde passieren? Wird MySQL Server das nicht ausführen?
Wird das PreparedStatement eine Exception werfen?
Entschuldigung wegen der unpräzisen Aussage :/


----------



## Michael... (23. Okt 2009)

Ausgeführt wird da nichts, durch die PreparedStmts kann man eben solche SQL Injections verhindern. Die Datenbank würde einfach versuchen den String "Drop buecherTabelle" in das Feld isbn zu schreiben. Eventuell würde die Datenbank einen Fehler melden, wenn z.B die zulässige Anzahl der Character des Feldes überschritten wiird.
Aber speziell bei so Dingen wie ISBN sollte man ja sowieso überprüfen, ob es sich bei der Eingabe tatsächlich um eine gültige ISBN handelt.


----------



## Meldanor (23. Okt 2009)

Also ist es möglich mit einem PreparedStatement bösartigen Code einzuschleusen ohne jeden String auf Schlüsselwörter zu untersuchen?
Wenn ja, was wäre der beste Weg? Weil wenn z.B. ein Buch "Insert,Delete und Update - Learn MySQL" heißt, würde das Programm es zurückweisen.


----------



## tfa (23. Okt 2009)

Meldanor hat gesagt.:


> Also ist es möglich mit einem PreparedStatement bösartigen Code einzuschleusen ohne jeden String auf Schlüsselwörter zu untersuchen?
> Wenn ja, was wäre der beste Weg? Weil wenn z.B. ein Buch "Insert,Delete und Update - Learn MySQL" heißt, würde das Programm es zurückweisen.



Nein, das ist nicht möglich. Das haben Michael und ARadauer doch schon erklärt.
Mit Prepared Statements würde in der Tabellenspalte dann eben z.B. "DROP buechertabelle" stehen. Da wird nichts ausgeführt.


----------



## Meldanor (23. Okt 2009)

Okay, danke, jetzt hab ich es verstanden ^^


----------



## bronks (24. Okt 2009)

Meldanor hat gesagt.:


> ... dass ein neuer MySQL Befehl mit eingeschleust wird? So dass kein "böser Mensch" statt einer ISBN 3-978-54545-12 einfach
> 
> ```
> DROP buecherTabelle;
> ...


Mit einem einfachen [DROP buecherTabelle;] ist so ein Hack nicht erledigt. Da muß etwas mehr geschrieben werden, damit die Datenbank keinen Fehler meldet und der Fremdcode ausgeführt wird. Dafür muß man die App selbst gut kennen, was v.a. bei OpenSource, wie z.B. PHPBB zum Problem wurde.


----------



## Meldanor (24. Okt 2009)

bronks hat gesagt.:


> Mit einem einfachen [DROP buecherTabelle;] ist so ein Hack nicht erledigt. Da muß etwas mehr geschrieben werden, damit die Datenbank keinen Fehler meldet und der Fremdcode ausgeführt wird. Dafür muß man die App selbst gut kennen, was v.a. bei OpenSource, wie z.B. PHPBB zum Problem wurde.



Aber es sollte reichen, wenn ich ein paar .... nicht gerade erwachsen denkenden Leuten abhalten kann, so etwas zu machen.


----------

