Aman
query.SQL.Text := 'select * from table_name where name=:Name';
Kode ini aman karena Anda menggunakan parameter.
Parameter selalu aman dari injeksi SQL.
Tidak aman
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;
Tidak aman karena Nama Pengguna bisa berupa name; Drop table_name;
Menghasilkan kueri berikut yang dieksekusi.
select * from table_name where name=name; Drop table_name;
Juga Tidak Aman
var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';
Karena jika username adalah ' or (1=1); Drop Table_name; --
Ini akan menghasilkan kueri berikut:
select * from table_name where name='' or (1=1); Drop Table_name; -- '
Tapi kode ini aman
var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);
Karena IntToStr()
hanya akan menerima bilangan bulat sehingga tidak ada kode SQL yang dapat disuntikkan ke dalam string kueri dengan cara ini, hanya angka (yang persis seperti yang Anda inginkan dan dengan demikian diizinkan)
Tetapi saya ingin melakukan hal-hal yang tidak dapat dilakukan dengan parameter
Parameter hanya dapat digunakan untuk nilai. Mereka tidak dapat mengganti nama bidang atau nama tabel. Jadi jika Anda ingin menjalankan kueri ini
query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName; {works, but is unsafe}
Kueri pertama gagal karena Anda tidak dapat menggunakan parameter untuk nama tabel atau bidang.
Kueri kedua tidak aman, tetapi apakah ini satu-satunya cara yang dapat dilakukan.
Bagaimana agar Anda tetap aman?
Anda harus memeriksa string tablename
terhadap daftar nama yang disetujui.
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;
...
Itulah satu-satunya cara untuk melakukan ini, yang saya tahu.
BTW Kode asli Anda mengalami kesalahan:
query.SQL.Text := 'select * from table_name where name=:Name where id=:ID';
Seharusnya
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
Anda tidak dapat memiliki dua where
ada dalam satu (sub)kueri