Säkert
query.SQL.Text := 'select * from table_name where name=:Name';
Den här koden är säker eftersom du använder parametrar.
Parametrar är alltid säkra från SQL-injektion.
Osäkert
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Är osäker eftersom användarnamn kan vara name; Drop table_name;
Detta resulterar i att följande fråga exekveras.
select * from table_name where name=name; Drop table_name;
Också Osäkert
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Eftersom det är om användarnamn är ' or (1=1); Drop Table_name; --
Det kommer att resultera i följande fråga:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Men den här koden är säker
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Eftersom IntToStr()
accepterar bara heltal så ingen SQL-kod kan injiceras i frågesträngen på det här sättet, bara siffror (vilket är exakt vad du vill ha och därmed tillåtet)
Men jag vill göra saker som inte kan göras med parametrar
Parametrar kan endast användas för värden. De kan inte ersätta fältnamn eller tabellnamn. Så om du vill köra den här frågan
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
Den första frågan misslyckas eftersom du inte kan använda parametrar för tabell- eller fältnamn.
Den andra frågan är osäker men är det enda sättet detta kan göras på.
Hur håller du dig säker?
Du måste kontrollera strängen tablename
mot en lista över godkända namn.
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;
...
Det är det enda sättet att göra detta, som jag känner till.
BTW Din ursprungliga kod har ett fel:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Borde vara
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Du kan inte ha två where
är i en (under)fråga