Sicher
query.SQL.Text := 'select * from table_name where name=:Name';
Dieser Code ist sicher, weil Sie Parameter verwenden.
Parameter sind immer sicher vor SQL-Injection.
Unsicher
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Ist unsicher, weil Benutzername name; Drop table_name;
Dies führt dazu, dass die folgende Abfrage ausgeführt wird.
select * from table_name where name=name; Drop table_name;
Auch Unsicher
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Denn wenn der Benutzername ' or (1=1); Drop Table_name; --
Das Ergebnis ist die folgende Abfrage:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Aber dieser Code ist sicher
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Denn IntToStr()
akzeptiert nur Ganzzahlen, daher kann auf diese Weise kein SQL-Code in die Abfragezeichenfolge eingefügt werden, sondern nur Zahlen (was genau das ist, was Sie wollen und daher erlaubt sind)
Aber ich möchte Sachen machen, die nicht mit Parametern gemacht werden können
Parameter können nur für Werte verwendet werden. Sie können keine Feldnamen oder Tabellennamen ersetzen. Wenn Sie also diese Abfrage ausführen möchten
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
Die erste Abfrage schlägt fehl, weil Sie keine Parameter für Tabellen- oder Feldnamen verwenden können.
Die zweite Abfrage ist unsicher, aber die einzige Möglichkeit, dies zu tun.
Wie bleiben Sie sicher?
Sie müssen den String tablename
überprüfen gegen eine Liste genehmigter Namen.
Const
ApprovedTables: array[0..1] of string = ('table1','table2');
procedure DoQuery(tablename: string);
var
i: integer;
Approved: boolean;
query: string;
begin
Approved:= false;
for i:= lo(ApprovedTables) to hi(ApprovedTables) do begin
Approved:= Approved or (lowercase(tablename) = ApprovedTables[i]);
end; {for i}
if not Approved then exit;
query:= 'SELECT * FROM '+tablename;
...
Das ist die einzige Möglichkeit, dies zu tun, die ich kenne.
Übrigens Ihr ursprünglicher Code enthält einen Fehler:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Sollte
seinquery.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Sie können nicht zwei where
haben 's in einer (Unter-)Abfrage