2012-06-20 1 views
7

Ich weiß über die Verwendung von Parametern in SQL-Sätzen, aber nur aus Neugier ist sicher, die Format-Funktion zu verwenden, um SQL-Injektionen anstelle von Parametern zu verhindern.Format Funktion vs Parameter in SQL-Injektion Szenarien?

wie diese Probe

sCustomer : string 
begin 
AdoSql.CommandText:=Format('Select SUM(value) result from invoices where customer=%s',[QuotedStr(sCustomer)]); 
end; 
+1

Ich denke, Titel sollte 'QuotedStr Funktion vs Parameter in SQL-Injektionen Szenarien?' Aber ändern, wird hier einige Antworten brechen. Das * Problem * hier ist über 'QuotedStr' und nicht' Format'. – kobik

Antwort

11

Das wäre wahrscheinlich gegen SQL-Injection sicher sein, vorausgesetzt, QuotedStr funktioniert wie erwartet und es gibt keine Grenzfälle, die es brechen kann. (Was keineswegs garantiert ist. Wie Linas in einem Kommentar darauf hingewiesen hat, lässt MySql \' verwenden, um Anführungszeichen zu umgehen. Andere DBMS haben wahrscheinlich ähnliche Fähigkeiten. Ein Angreifer mit genügend theoretischem Wissen über das System könnte sie ausnutzen.)

Aber selbst wenn QuotedStr gut genug ist, ist es immer noch besser, Parameter aus einem anderen Grund zu verwenden: Leistung. Wenn Sie Ihre Parameter von Ihrer Abfrage trennen, können Sie den gleichen Abfragecode mehrere Male mit verschiedenen Parametern senden. Wenn Sie das tun, kann die Datenbank einen Großteil der Arbeit, die sie bei der Berechnung der Abfrage leistet, zwischenspeichern, so dass Ihr DB-Zugriff schneller wird. Das funktioniert nicht (oder zumindest nicht so gut), wenn Sie die Parameter in den Abfragecode selbst mischen.

+6

+1 für den Kommentar über "Cache", viele SQL Server können den Ausführungsplan der SQL-Sentences wiederverwenden. – RRUZ

+3

Das wäre wahrscheinlich in MySQL unsicher, weil MySQL erlaubt, einem Zitat zu entkommen, so dass QuotedStr hier nicht helfen wird. – Linas

+0

@ Linas: Guter Punkt. Bearbeitet, um dies zu berücksichtigen. –

5

Jedes Mal, wenn Sie eine SQL-Zeichenfolge erstellen, indem Sie Zeichenfolgen miteinander verketten, besteht die Gefahr eines Injektionsangriffs, unabhängig davon, wie sicher der Zugriff auf diese Zeichenfolgen ist. Nach allem, was Sie wissen, könnte jemand Ihre App in einem Debugger ausführen, setzen Sie einen Haltepunkt auf das Ergebnis QuotedStr(), und ändern Sie den Inhalt vor dem Erlauben Format(), es zu sehen.

Die Verwendung von SQL-Parametern ist der sicherste Weg. Es vermeidet nicht nur Injektionen, sondern erlaubt auch der SQL-Engine, zu entscheiden, wie die Parameter am besten für ihre eigenen Bedürfnisse formatiert werden, so dass Sie sich keine Gedanken über die Formatierung der Werte in Ihrem eigenen Code machen müssen Sprachen (wie Delphi). Ganz zu schweigen von den Leistungsvorteilen, die es ermöglichen, die SQL-Anweisung auf der Serverseite im Voraus vorzubereiten, bevor sie dann in Ihrem Code mehrfach ausgeführt wird, wodurch der Datenverkehr zwischen Client und Server drastisch reduziert und die Gesamtleistung erhöht wird.

var 
    sCustomer : string 
begin 
    AdoSql.CommandText := 'Select SUM(value) result from invoices where customer=:Customer'; 
    AdoSql.Prepared := True; 
    ... 
    AdoSql.Parameters['Customer'].Value := sCustomer; 
    AdoSql1.ExecSQL; 
    ... 
    AdoSql.Parameters['Customer'].Value := sCustomer; 
    AdoSql1.ExecSQL; 
    ... 
    AdoSql.Prepared := False; 
end; 
+3

Dieser erste Absatz ist ein bisschen albern. Bei der SQL-Injection geht es hauptsächlich darum, unberechtigten Zugriff auf die Datenbank zu erlangen. Wenn jedoch jemand Zugriff auf die Debug-Ebene für Ihre App selbst hat, benötigt er * keinen SQL-Injection-Angriff, um Zugriff auf die Datenbank zu erhalten. Sie können davon ausgehen, dass sie bereits Zugriff auf dieselbe Privilegstufe wie die App selbst haben. –

+1

Nicht, wenn die Anwendung eine verschlüsselte Verbindung zur Datenbank verwendet oder wenn der Angreifer nicht bestimmen kann oder möchte, welche Art von Datenbank verwendet wird oder wie direkt auf sie zugegriffen werden kann. Lassen Sie die App die ganze Arbeit machen, ändern Sie einfach die SQL, die ausgeführt wird. –

+2

In diesem Szenario wäre die Verwendung von Parametern auch unsicher, da der Benutzer die Werte der Parameter ändern könnte - etwas, das ich manchmal beim Debuggen meiner eigenen Apps tue. –

5

Nein, Format bietet keine Sicherheit vor SQL-Injektion. Es unterscheidet sich in dieser Hinsicht nicht von der normalen String-Verkettung.

Der Teil des Codes in der Frage, der etwas gegen SQL-Injektion tut, ist der Aufruf an QuotedStr, die Sie mit oder ohne Format verwenden konnten. Es ist jedoch nicht so zuverlässig wie echte parametrisierte Abfragen. Der einzige Vorteil von Format in diesem Kontext ist, dass die gesamte Zeichenfolgenschablone an einer Stelle ist, sodass Sie weniger Abstand und Interpunktion falsch erhalten, als wenn Sie die Zeichenfolge mit aufeinanderfolgenden +-Operationen erstellen müssten , wobei die SQL-Apostrophe unter den Delphi-Apostrophen verloren gehen könnten.