Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL Injection verhindern? (https://www.delphipraxis.net/210421-sql-injection-verhindern.html)

NoGAD 22. Apr 2022 00:56

Datenbank: ABSDatabase • Version: 7.93 • Zugriff über: ABSQuery

SQL Injection verhindern?
 
Hallo,

durch die Nutzung von SQL für meine Datenbank habe ich überlegt, ob man eine SQL Injection erkennen kann.

Gibt es besondere Strings, die man z.B. bei einer Suche filtern sollte?

LG :-)

haentschman 22. Apr 2022 06:48

AW: SQL Injection verhindern?
 
Moin...:P

Ja kann man. Wenn man ausschließlich Parameter verwendet. :thumb:
Delphi-Quellcode:
Qry.SQL.Text := 'select Bla from Blubb where Blubchen = :BLA';
Qry.ParamByName('BLA').AsString := 'Blubb';
Qry.Open;

stifflersmom 22. Apr 2022 07:44

AW: SQL Injection verhindern?
 
Auf jeden Fall ein wichtiges und auch kein triviales Thema.

Injection bedeutet ja, dass irgendetwas in Deinen SQL-String eingefügt wird, was dann als zusätzlicher Befehl missbraucht wird.

Als Beispiel hast Du ein EditFeld und die Eingabe darin soll als Suchstring interpretiert werden, gedacht ist dann sowas wie:
Code:
'select * from Personen where Name = '+QuotedStr(Edit1.text)
Und wenn im Edit1 ein 'Hansen steht, dann würde daraus ein:
Code:
'select * from Personen where Name = 'Hansen';
So weit so gut, aber kommt über das Editfeld jetzt aber noch ein Hochkomma und ein Semikolon rein, dann könnte das dazu führen, dass ein zusätzlicher Befehl ausgeführt wird:
Code:
'select * from Personen where Name = 'Hansen'; DROP TABLE blablabla;'';
Hier würde jetzt also der zusätzliche Befehl DROP TABLE ... ausgeführt werden können.

Das war jetzt, sehr simpel, ein mögliches Szenario zusammengetippt.

haentschman 22. Apr 2022 08:22

AW: SQL Injection verhindern?
 
:zwinker:
Lesestoff: https://de.wikipedia.org/wiki/SQL-Injection

himitsu 22. Apr 2022 08:50

AW: SQL Injection verhindern?
 
@mom: NEIN!

QuotedStr ist für die Syntax von Pascal/Delphi-Strings,
dass es zufällig "oftmals" für SQL-Strings ausreicht, verhindet keine Injection/Maskierungsfehler.

Jede SQL-DB und SQL-API/Komponente hat irgendwo eine passende "Escape"-Funktion.

Frickler 22. Apr 2022 09:14

AW: SQL Injection verhindern?
 
Zitat:

Zitat von himitsu (Beitrag 1504935)
@mom: NEIN!

QuotedStr ist für die Syntax von Pascal/Delphi-Strings,
dass es zufällig "oftmals" für SQL-Strings ausreicht, verhindet keine Injection/Maskierungsfehler.

Hat er doch gar nicht behauptet.



P.S.: https://xkcd.com/327/

NoGAD 22. Apr 2022 09:49

AW: SQL Injection verhindern?
 
Danke für die Hinweise. Bitte nicht streiten. :-)

@haentschman, eine Nachfrage zum Syntax. Warum wird bei einer Suche ein : vor den Suchbegriff gestellt (:Bla)?

Eine weitere Frage bezüglich SQL injection: würde es ausreichen, Semikolons aus einem Suchbegriff zu entfernen?

mkinzler 22. Apr 2022 10:01

AW: SQL Injection verhindern?
 
Zitat:

Warum wird bei einer Suche ein : vor den Suchbegriff gestellt (:Bla)?
Kennzeichnet den Parameter/Platzhalter

haentschman 22. Apr 2022 10:03

AW: SQL Injection verhindern?
 
Zitat:

würde es ausreichen, Semikolons aus einem Suchbegriff zu entfernen
...nein. :wink:

Da sind wir wieder am Anfang: Immer Parameter! :warn: :zwinker:
Zitat:

Warum wird bei einer Suche ein : vor den Suchbegriff gestellt (:Bla)?
Delphi-Quellcode:
where Blubchen = :BLA
...Parameter beginnen immer mit :

Der Name des Parameters ist beliebig. Ich habe mich für 3 Großbuchstaben entschieden...:wink:

Rolf Frei 22. Apr 2022 14:52

AW: SQL Injection verhindern?
 
Zitat:

Zitat von NoGAD (Beitrag 1504944)
Danke für die Hinweise. Bitte nicht streiten. :-)

@haentschman, eine Nachfrage zum Syntax. Warum wird bei einer Suche ein : vor den Suchbegriff gestellt (:Bla)?

Eine weitere Frage bezüglich SQL injection: würde es ausreichen, Semikolons aus einem Suchbegriff zu entfernen?

Aus diesem Code:
Delphi-Quellcode:
Query.SQL.Text := 'select * from Personen where Name = '+QuotedStr(Edit1.Text);
Machst du das:
Delphi-Quellcode:
Query.SQL.Text := 'select * from Personen where Name = :NAME';
Query.ParamByName('NAME').AsString := Edit1.Text;
Dadurch ist dein Code geschützt vor Injections. Also nie einen SQL String direkt mit den Eingaben eines Users zusammenbauen! Was da im Edit.Text drin steht ist dann vollkommen egal, da dieses nicht mehr Bestandteil des SQL ist und somit auch nicht ausgeführt wird.

NoGAD 22. Apr 2022 18:06

AW: SQL Injection verhindern?
 
Zitat:

Zitat von Rolf Frei (Beitrag 1504973)
Query.SQL.Text := 'select * from Personen where Name = :NAME';
Query.ParamByName('NAME').AsString := Edit1.Text;


Hallo und Danke.

Ich verstehe das leider immer noch nicht.

Wenn ich einen Suchstring habe, dann sollte doch auch damit gearbeitet werden?

Wie wird denn :NAME initialisiert?

LG :-)


Selbst die Erklärung von componentace hilft mir nicht, es zu verstehen: http://www.componentace.com/help/abs...sinqueries.htm

mkinzler 22. Apr 2022 18:50

AW: SQL Injection verhindern?
 
Ein (SQL-)Parameter ist ein/eine Platzhalter/Variable.

Es wird keine Abfrage auf einen aktuellen Wert gemacht sondern auf den Parameter NAME
Delphi-Quellcode:
Query.SQL.Text := 'select * from Personen where Vorname = :NAME';
Den Wert wird hiermit gesetzt:
Delphi-Quellcode:
Query.ParamByName('NAME').AsString := 'Egon';
Query.Open;
Nun werden alle Personmen mit dem Vornamen "Egon" angezeigt.
Delphi-Quellcode:
Query.ParamByName('NAME').AsString := 'Susi';
Query.Open;
Nun alle Susis.

jobo 22. Apr 2022 19:03

AW: SQL Injection verhindern?
 
[QUOTE=NoGAD;1504988]
Zitat:

Zitat von Rolf Frei (Beitrag 1504973)


Wie wird denn :NAME initialisiert?


Als Ergänzung, Delphi sucht aus dem SQL die Parameter raus. So kannst Du sie über ParamByName ansprechen. Die Namen legst Du selbst im SQL Statement fest.
Bei diesem Verfahren kannst Du nicht nur den Wert angeben, sondern auch den Typ berücksichtigen, String, Datum, Zahl .. schau es Dir an.
Damit erschlägst Du auch gleich Konvertierungsprobleme, Quoting und eben Injection.

coasting 22. Apr 2022 19:58

AW: SQL Injection verhindern?
 
Zitat:

Wie wird denn :NAME initialisiert?


Die Parameter werden über die Params Eigenschaft des TABSQuery Objekts definiert. Dort können auch weitere Eigenschaften wie zB der Datentyp vorgegeben werden.

NoGAD 22. Apr 2022 21:01

AW: SQL Injection verhindern?
 
Ganz, ganz herzlichen Dank, dass ihr euch so viel Mühe mit mir gebt.

Trotzdem geht es mir nicht in den Kopf, warum mittels Parameter ein Code nicht ausgeführt werden kann..

Delphi-Quellcode:
Query.SQL.Text := 'select * from Personen where Vorname = :NAME';
Query.ParamByName('NAME').AsString := 'Egon';
Query.Open;
Statt 'Egon' würde dann eigentlich die Suchanfrage als Variable eingesetzt werden?

Delphi-Quellcode:
Query.ParamByName('NAME').AsString := Edit1.Text;
Query.Open;

???

Und in diesem Fall würde ein Datenbankbefehl ins Leere laufen?

LG :-)

jobo 22. Apr 2022 21:33

AW: SQL Injection verhindern?
 
Zitat:

Zitat von NoGAD (Beitrag 1504994)
..
Und in diesem Fall würde ein Datenbankbefehl ins Leere laufen?

Na probiers aus. Es beißt nicht.

Wenn überall davor gewarnt wird, Injections zu vermeiden, dann ist das so ähnlich, wie die Warnung vor dem Umspannhäuschen mit Schildern: Achtung Starkstrom.
Man könnte argumentieren, die Techniker gehen ja auch da rein und kommen lebend wieder raus. Tatsächlich! Und niemand weiß, was in den Häuschen geschieht.
Bei SQL ist das anders. Und ehrlich, wenn es Dir bis jetzt egal war oder zu kompliziert mit SQL, willst Du 1000 Details wissen?

Allein mein Hinweis, dass Du damit Typen behandeln kannst, erklärt für alle Typen außer Text, dass Injection nicht möglich ist. Du kannst kein SQL Text in einen Parameter vom Typ Integer packen. Das fliegt Dir schon im Client um die Ohren.

Bleibt der Text Typ, also Dein Beispiel mit Egon. Ich kann die Frage verstehen.
Ich kann es nicht für alle DB sagem (z.B. ABS habe ich einmal im Leben benutzt und es interessiert mich nicht. Für mich ist es so: ist ein guter Schritt weg von BDE, aber auch zu kurz gesprungen. Naja ist auch abhängig vom Einsatzzweck), aber die Parameter Auflösung geschieht erst auf dem Server (den es bei ABS so nicht gibt). Wenn das unbefüllte Statement beim Server ankommt, geschehen viele Dinge, die einen theoretisch nicht interessieren müssen (Blackbox Prinzip). Oft ergibt sich das Interesse erst zwangsweise, bei Fehlern oder schlechter Performance. Eine Sache ist die Query Planung. Der Server analysiert, wie er die Abfrage am schnellsten ausführen kann. Dabei spielen z.B. vorhandene Indizes eine Rolle. Diese Query Planung kostet wiederum Zeit. Um die zu sparen, geschieht zuerst etwas ziemlich billiges. Der Server schaut in der Liste der bereits geplanten Queries, ob er die gleiche Query bereits geplant hat. Dabei wird ein simpler Textvergleich z´wischen alten und der neuen Query durchgeführt. Eine nicht-parametrierte Query wird selten zu einem Treffer führen bei dieser Suche. Außer es wird ständig der gleiche Egon gesucht. Steht statt Egon eine feste Variable in der Query, funktioniert der Mechanismus bestens. Die neue wird bei den geplanten Queries gefunden, Planung bereits vorhanden, Analyse fällt weg. Erst jetzt wird der übegebene Parameter eingesetzt. An dieser Stelle liegt es in den Händen des Serverherstellers, wie er mit dem Problem Injection umgeht. Die haben da auch kein Bock drauf.

Du kannst das alles ergründen und ausprobieren für ABS oder andere Anbieter oder Du kannst die Spielregeln akzeptieren. Es gibt andere Mechanismen, die Injection verhindern und es gibt noch andere Vorteile bei parametrierten Queries.
Zu allem gibt es massig Infos im Internet und wahrscheinlich auch für ABS. Für sowas sucht man sich ein Tutorial oder die Handbücher raus und schaut sich die Erklärungen an oder fragt in den Anbieterforen. Sogar die Kommandozeilen Clients der Anbieter erlauben es, parametrierte Queries zu starten. Das gibt es nicht zum Spaß. Und bei Delphi hat man sogar etwas Komfort bei der Befüllung.

NoGAD 22. Apr 2022 22:17

AW: SQL Injection verhindern?
 
Recht herzlichen Dank!

Ich werde mich belesen.

Lg

hoika 23. Apr 2022 17:49

AW: SQL Injection verhindern?
 
Hallo,
Zitat:

Ganz, ganz herzlichen Dank, dass ihr euch so viel Mühe mit mir gebt.
Trotzdem geht es mir nicht in den Kopf, warum mittels Parameter ein Code nicht ausgeführt werden kann..
Bitte ;)

Zuerst wird der SQL-Befehl übermittelt und danach die Parameter.

Das heißt:
1. SQL-Befehl analysieren, (Prepare)
2. Werte der Parameter einfügen, und das Drop Table ist dann kein Befehl mehr, sondern gehört zum Where.

Where "Egon;Drop Table1" wird dann also ins Leere laufen

Ein
Select Id From Person
Where Name="Egon";
Drop Table Tabelle1

ist was gaaanz anderes.
Zuerst das Select, dann das Drop


Durch die explizite Benutzung der Parameter teilt man der DB also mit,
dass man (hier) ein Select machen will.

NoGAD 23. Apr 2022 18:16

AW: SQL Injection verhindern?
 
Danke Heiko,

so schön erklärt ist es endlich verständlich.

Die reinen Abhandlungen, wie was gemacht wird, ist meistens schön und gut, der Hintergrund fehlt mir leider in vielen Fällen.

LG und ein schönes Wochenende :-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz