sql >> Database >  >> RDS >> Oracle

Delphi - voorkomen tegen SQL-injectie

Veilig

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

Deze code is veilig omdat je parameters gebruikt.
Parameters zijn altijd veilig voor SQL-injectie.

Onveilig

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

Is onveilig omdat gebruikersnaam name; Drop table_name; Met als resultaat dat de volgende query wordt uitgevoerd.

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

Ook Onveilig

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

Omdat het als gebruikersnaam ' or (1=1); Drop Table_name; -- Het zal resulteren in de volgende vraag:

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

Maar deze code is veilig

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

Omdat IntToStr() accepteert alleen gehele getallen, dus er kan op deze manier geen SQL-code in de queryreeks worden geïnjecteerd, alleen cijfers (wat precies is wat u wilt en dus is toegestaan)

Maar ik wil dingen doen die niet met parameters kunnen

Parameters kunnen alleen voor waarden worden gebruikt. Ze kunnen geen veldnamen of tabelnamen vervangen. Dus als u deze zoekopdracht wilt uitvoeren

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

De eerste query mislukt omdat u geen parameters voor tabel- of veldnamen kunt gebruiken.
De tweede query is onveilig, maar is de enige manier waarop dit kan worden gedaan.
Hoe blijft u veilig?

Je moet de string tablename . aanvinken tegen een lijst van goedgekeurde namen.

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

Dat is de enige manier om dit te doen, voor zover ik weet.

BTW Uw originele code bevat een fout:

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

Zou moeten zijn

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

U kunt geen twee where . hebben 's in één (sub)query



  1. Voorwaardelijk OP DUPLICATE KEY UPDATE (alleen bijwerken als aan bepaalde voorwaarde wordt voldaan)

  2. Strings ontsnappen met python mysql.connector

  3. Hoe COT() werkt in MariaDB

  4. Zijn geneste haakjes in de FROM-clausule geldige Oracle SQL-syntaxis?