Sicuro
query.SQL.Text := 'select * from table_name where name=:Name';
Questo codice è sicuro perché stai usando parametri.
I parametri sono sempre al sicuro dall'iniezione SQL.
Non sicuro
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Non è sicuro perché il nome utente potrebbe essere name; Drop table_name;
Con conseguente esecuzione della query seguente.
select * from table_name where name=name; Drop table_name;
Inoltre Non sicuro
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Perché se il nome utente è ' or (1=1); Drop Table_name; --
Risulterà nella seguente query:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Ma questo codice è sicuro
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Perché IntToStr()
accetterà solo numeri interi, quindi nessun codice SQL può essere iniettato nella stringa di query in questo modo, solo numeri (che è esattamente quello che vuoi e quindi consentito)
Ma voglio fare cose che non possono essere fatte con i parametri
I parametri possono essere utilizzati solo per i valori. Non possono sostituire i nomi dei campi o delle tabelle. Quindi, se vuoi eseguire questa query
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
La prima query ha esito negativo perché non è possibile utilizzare i parametri per i nomi di tabelle o campi.
La seconda query non è sicura ma è l'unico modo in cui è possibile farlo.
Come mantenersi al sicuro?
Devi controllare la stringa tablename
contro un elenco di nomi approvati.
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;
...
Questo è l'unico modo per farlo, che io sappia.
BTW Il tuo codice originale ha un errore:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Dovrebbe essere
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Non puoi avere due where
è in una (sotto)query