Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Delphi - ngăn chặn việc tiêm SQL

An toàn

query.SQL.Text := 'select * from table_name where name=:Name';

Mã này an toàn vì bạn đang sử dụng các tham số.
Các tham số luôn an toàn trước SQL-injection.

Không an toàn

var Username: string;
...
query.SQL.Text := 'select * from table_name where name='+ UserName;

Không an toàn vì Tên người dùng có thể là tên name; Drop table_name; Dẫn đến truy vấn sau được thực thi.

select * from table_name where name=name; Drop table_name;

Ngoài ra Không an toàn

var Username: string;
...
query.SQL.Text := 'select * from table_name where name='''+ UserName+'''';

Bởi vì nó nếu tên người dùng là ' or (1=1); Drop Table_name; -- Nó sẽ dẫn đến truy vấn sau:

select * from table_name where name='' or (1=1); Drop Table_name; -- '

Nhưng mã này an toàn

var id: integer;
...
query.SQL.Text := 'select * from table_name where id='+IntToStr(id);

Bởi vì IntToStr() sẽ chỉ chấp nhận các số nguyên vì vậy không có mã SQL nào có thể được đưa vào chuỗi truy vấn theo cách này, chỉ các số (chính xác là những gì bạn muốn và do đó được phép)

Nhưng tôi muốn thực hiện những việc không thể thực hiện được với các tham số

Tham số chỉ có thể được sử dụng cho các giá trị. Chúng không thể thay thế tên trường hoặc tên bảng. Vì vậy, nếu bạn muốn thực hiện truy vấn này

query:= 'SELECT * FROM :dynamic_table '; {doesn't work}
query:= 'SELECT * FROM '+tableName;      {works, but is unsafe}

Truy vấn đầu tiên không thành công vì bạn không thể sử dụng các tham số cho tên bảng hoặc trường.
Truy vấn thứ hai không an toàn nhưng là cách duy nhất có thể thực hiện điều này.
Làm cách nào để bạn giữ an toàn?

Bạn phải kiểm tra chuỗi tablename chống lại một danh sách các tên đã được phê duyệt.

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;
  ...

Đó là cách duy nhất để làm điều này mà tôi biết.

BTW Mã ban đầu của bạn có lỗi:

query.SQL.Text := 'select * from table_name where name=:Name where id=:ID'; 

Nên

query.SQL.Text := 'select * from table_name where name=:Name and id=:ID'; 

Bạn không thể có hai where 's trong một (con) truy vấn



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tạo một hàm pl / sql và tìm năm nhuận

  2. Truy vấn đệ quy Oracle - Ngày tháng

  3. Chuyển và trả về đối tượng mảng tùy chỉnh trong ibatis và oracle trong java

  4. Làm thế nào để kết nối với Oracle 10g từ máy khách từ xa?

  5. Lược đồ khung thực thể độc lập Mã Di chuyển đầu tiên