I need to protect an application from SQL injection. Application is connecting to Oracle, using ADO, and search for the username and password to make the authentication.
From what I’ve read until now, the best approach is by using parameters, not assigning the entire SQL as string. Something like this:
query.SQL.Text := 'select * from table_name where name=:Name and id=:ID';
query.Prepare;
query.ParamByName( 'Name' ).AsString := name;
query.ParamByName( 'ID' ).AsInteger := id;
query.Open;
Also, I’m thinking to verify the input from user, and to delete SQL keywords like delete,insert,select,etc…Any input character different than normal ASCII letters and numbers will be deleted.
This will assure me a minimum of security level?
I do not want to use any other components than Delphi 7 standard and Jedi.
Safe
This code is safe because you are using parameters.
Parameters are always safe from SQL-injection.
Unsafe
Is unsafe because Username could be
name; Drop table_name;Resulting in the following query being executed.
Also Unsafe
Because it if username is
' or (1=1); Drop Table_name; --It will result in the following query:
But this code is safe
Because
IntToStr()will only accept integers so no SQL code can be injected into the query string this way, only numbers (which is exactly what you want and thus allowed)But I want to do stuff that can’t be done with parameters
Parameters can only be used for values. They cannot replace field names or table names.
So if you want to execute this query
The first query fails because you cannot use parameters for table or field names.
The second query is unsafe but is the only way this this can be done.
How to you stay safe?
You have to check the string
tablenameagainst a list of approved names.That’s the only way to do this, that I know of.
BTW Your original code has an error:
Should be
You cannot have two
where‘s in one (sub)query