reales pagina mas kali inyecciones inyeccion injection hackear ejemplos ejemplo comunes casos sql oracle delphi sql-injection

pagina - sql injection ejemplos reales



Delphi: evita la inyección de SQL (3)

Esto me asegurará un mínimo de nivel de seguridad?

Sí, las consultas parametrizadas deberían protegerlo de la inyección SQL, que sería fácil de probar. Simplemente ingrese una cadena peligrosa en la variable de name y vea qué sucede. Normalmente deberías obtener 0 filas devueltas y no un error.

Necesito proteger una aplicación de inyección SQL. La aplicación se conecta a Oracle, utilizando ADO, y busca el nombre de usuario y la contraseña para realizar la autenticación.

Por lo que he leído hasta ahora, el mejor enfoque es usar parámetros, no asignar todo el SQL como cadena. Algo como esto:

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;

Además, estoy pensando en verificar la entrada del usuario y eliminar palabras clave de SQL como eliminar, insertar, seleccionar, etc. Se eliminará cualquier carácter de entrada diferente a las letras y números ASCII normales.

Esto me asegurará un mínimo de nivel de seguridad?

No quiero usar ningún otro componente que el estándar Delphi 7 y el Jedi.


Si permite que el usuario influya solo en el valor de los parámetros que se vincularán en un texto de comando sql con marcadores de posición, entonces realmente no necesita inspeccionar lo que el usuario ingresa: la forma más simple de evitar la inyección SQL, como usted menciona, es evitar SQL concatenado, y usar variables enlazadas (o procedimientos de llamada) lo hace (también tiene la ventaja - el kilometraje / relevancia depende de la base de datos - de permitir que el motor reutilice los planes de consulta).

Si está utilizando Oracle, entonces debe tener una buena razón para no usar variables vinculadas: Tom Kyte tiene mucha información sobre esto en su sitio http://asktom.oracle.com . Simplemente ingrese "variables enlazadas" en el cuadro de búsqueda.


Seguro

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

Este código es seguro porque estás usando parámetros.
Los parámetros están siempre seguros de la inyección de SQL.

Inseguro

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

No es seguro porque el name; Drop table_name; usuario podría ser el name; Drop table_name; name; Drop table_name; Como resultado, se ejecuta la siguiente consulta.

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

También inseguro

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

Porque si el nombre de usuario es '' or (1=1); Drop Table_name; -- '' or (1=1); Drop Table_name; -- '' or (1=1); Drop Table_name; -- Se generará la siguiente consulta:

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

Pero este código es seguro

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

Debido a que IntToStr() solo aceptará enteros, por lo que no se puede IntToStr() código SQL en la cadena de consulta de esta manera, solo números (que es exactamente lo que quiere y, por lo tanto, permite)

Pero quiero hacer cosas que no se pueden hacer con parámetros

Los parámetros solo se pueden usar para valores. No pueden reemplazar nombres de campos o tablas. Entonces, si quieres ejecutar esta consulta

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

La primera consulta falla porque no puede usar parámetros para nombres de tablas o campos.
La segunda consulta no es segura, pero es la única manera en que esto se puede hacer.
¿Cómo te mantienes seguro?

tablename verificar el nombre de tablename cadena con una lista de nombres aprobados.

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

Esa es la única forma de hacer esto, que yo sepa.

Por cierto, su código original tiene un error:

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

Debiera ser

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

No puede tener dos where una (sub) consulta