Güvenli
query.SQL.Text := 'select * from table_name where name=:Name';
Bu kod güvenlidir.
Parametreler, SQL-enjeksiyondan her zaman güvenlidir. Kullanıcı adı aşağıdaki sorguda Ortaya name; Drop table_name;
yürütülmektedir olabilir çünkü
Güvensiz
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
güvensiz mi.
select * from table_name where name=name; Drop table_name;
Ayrıca Güvensiz
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
adı ' or (1=1); Drop Table_name; --
ise o Aşağıdaki sorguda neden olur çünkü:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Ama bu kod güvenlidir
Hiçbir SQL kodu, sorgu dizesine yalnızca sayıları
bu şekilde enjekte edilebilir böylece IntToStr()
sadece
(tam olarak ne istediğinizi ve bu nedenle izin veren) tamsayılar kabul eder Ama yapmak istediğim
var id: integer; ... query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Çünkü
Parametreler ile yapılamayan parametreler sadece değerler için kullanılabilir. Alan adlarını veya tablo adlarını değiştiremezler. Yani tablo veya alan adları için parametreleri kullanamazsınız çünkü ilk sorgu başarısız olur bu sorgu
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
yürütmek istiyorum.
İkinci sorgu güvenli değil, ancak bunun yapılabilmesi için tek yoldur.
Nasıl güvenli kaldınız?
Onaylanmış adların bir listesine karşı tablename
dizesini kontrol etmeniz gerekir.
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;
...
Bunu yapmanın tek yolu bu, bildiğim.
BTW Orijinal kod bir hata var:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
tek bir (alt) sorgusu
Teşekkür ederim Johan. Soruyu düzelttim. + 1 – RBA
+1 birden fazla senaryoyu örtmek için –
Ama yine de SQL parametresini 'name; Tablo_adı; Drop kullanıcı tarafından girildiğinde, bu tür giriş kutusuna –