sql >> Database teknologi >  >> RDS >> Oracle

Delphi - forebygge mod SQL-injektion

Sikker

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

Denne kode er sikker, fordi du bruger parametre.
Parametre er altid sikre mod SQL-injektion.

Usikker

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

Er usikker, fordi brugernavn kunne være name; Drop table_name; Det resulterer i, at følgende forespørgsel udføres.

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

Også Usikker

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

Fordi det hvis brugernavn er ' or (1=1); Drop Table_name; -- Det vil resultere i følgende forespørgsel:

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

Men denne kode er sikker

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

Fordi IntToStr() vil kun acceptere heltal, så ingen SQL-kode kan injiceres i forespørgselsstrengen på denne måde, kun tal (hvilket er præcis, hvad du ønsker og dermed tilladt)

Men jeg vil gerne gøre ting, der ikke kan gøres med parametre

Parametre kan kun bruges til værdier. De kan ikke erstatte feltnavne eller tabelnavne. Så hvis du vil udføre denne forespørgsel

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

Den første forespørgsel mislykkes, fordi du ikke kan bruge parametre til tabel- eller feltnavne.
Den anden forespørgsel er usikker, men er den eneste måde, dette kan gøres på.
Hvordan forbliver du sikker?

Du skal tjekke strengen tablename mod en liste over godkendte navne.

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

Det er den eneste måde at gøre dette på, som jeg kender til.

BTW Din originale kode har en fejl:

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

Bør være

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

Du kan ikke have to where er i én (under)forespørgsel



  1. SQL Valg af MIN-værdi fra rækkedata med null-værdier

  2. Kortlæg oraklets type med dvale

  3. Hvordan eksporterer man en mysql-database ved hjælp af kommandoprompt?

  4. TABLOCK vs TABLOCKX