Сейф
query.SQL.Text := 'select * from table_name where name=:Name';
Этот код безопасен, потому что вы используете параметры.
Параметры всегда защищены от SQL-инъекций.
небезопасный
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Небезопасно, поскольку имя пользователя может быть name; Drop table_name;
В результате выполняется следующий запрос.
select * from table_name where name=name; Drop table_name;
Также Небезопасно
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Потому что это, если имя пользователя ' or (1=1); Drop Table_name; --
Это приведет к следующему запросу:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Но этот код безопасен
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Поскольку IntToStr()
будет принимать только целые числа, поэтому код SQL не может быть введен в строку запроса таким образом, только цифры (это именно то, что вы хотите и, следовательно, разрешено)
Но я хочу сделать то, что нельзя сделать с параметрами
Параметры могут использоваться только для значений. Они не могут заменить имена полей или имена таблиц.
Так что если вы хотите выполнить этот запрос
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
Первый запрос не выполнен, поскольку вы не можете использовать параметры для имен таблиц или полей.
Второй запрос небезопасен, но это единственный способ сделать это.
Как оставаться в безопасности?
Вы должны проверить строку tablename
по списку утвержденных имен.
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;
...
Это единственный известный мне способ сделать это.
BTW Ваш исходный код содержит ошибку:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Должно быть
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Вы не можете иметь два where
в одном (под) запросе