2009-03-26 15 views
13

¿Podría alguien indicarme una buena guía para principiantes sobre la ejecución segura de consultas SQL formadas en parte a partir de la entrada del usuario? Estoy usando Java, pero una guía de idioma neutral también está bien.¿Cómo debo desinfectar la entrada de la base de datos en Java?

El comportamiento deseado es que si alguien escribe en la GUI algo así como

very nice;) DROP TABLE FOO;

La base de datos debe tratar como una cadena literal y almacenar de forma segura sin dejar caer ninguna tabla.

Respuesta

5

Normalmente, no se debe crear una consulta de la concatenación de entrada, pero utilizando en su lugar PreparedStatement.

Eso le permite especificar en qué lugares va a establecer sus parámetros dentro de su consulta, por lo que Java se encargará de desinfectar todas las entradas para usted.

3

PreparedStatement? Si, absolutamente. Pero creo que hay un paso más: la validación de la entrada de la IU y el enlace a los objetos antes de acercarse a la base de datos.

puedo ver que la unión de una cadena de PreparedStatement todavía le podría dejar vulnerable a un ataque de inyección SQL:

String userInput = "Bob; DELETE FROM FOO"; 
String query = "SELECT * FROM FOO WHERE NAME = ?"; 

PreparedStatement ps = connection.prepareStatement(query); 
ps.setString(1, userInput); 
ps.executeQuery(); 

Tengo que admitir que no he probado a mí mismo, pero si esto es de forma remota Es posible que yo diga que PreparedStatement es necesario pero no suficiente. Validar y enlazar en el lado del servidor es la clave.

Recomendaría hacerlo con la API de enlace de Spring.

+0

Este es exactamente el tipo de ataque contra el que las declaraciones preparadas pretenden proteger. Escapará del; – danieltalsky

+0

Técnicamente, la interfaz PreparedStatement no lo garantiza. Aunque si su controlador hace algo diferente, busque un nuevo proveedor. –

+0

@daniel - Tendré que probarlo y verlo por mí mismo. Si estoy en lo cierto al respecto o no, ¿no está de acuerdo en que la validación del lado del servidor sigue siendo una buena idea? – duffymo

3

Su entrada del usuario en realidad tendría que ser "Bob'; delete from foo; select '" (o algo así) por lo que las cotizaciones implícitas añadidas por la declaración preparada estarían cerradas:

SELECT * FROM FOO WHERE NAME = 'Bob'; delete from foo; select '' 

pero si lo hace que el código de declaración preparada a citar su cotización para que pueda obtener una consulta real de

SELECT * FROM FOO WHERE NAME = 'Bob''; delete from foo; select ''' 

y su nombre se almacena como "Bob', delete from foo; select '" en lugar de ejecutar varias consultas.

Cuestiones relacionadas