¿Alguna base de datos le permite deshabilitar consultas no parametrizadas y, por lo tanto, deshabilitar la inyección de SQL?

5

¿Hay una base de datos que ya lo permita?

Si no, así es como creo que podría hacerse. Creo que sería necesario modificar el software de la base de datos y el controlador o el código que está ensamblando la consulta SQL. Creo que a veces esto lo hace la propia base de datos y otras veces el controlador.

Una configuración como 'Solo parámetros seguros' se habilitaría para la cuenta de usuario de la base de datos utilizada por el servidor web. Si está habilitado, solo se permitirán los parámetros marcados como seguros. El protocolo de red de la base de datos debe tener la capacidad para que el controlador comunique que los parámetros en la consulta fueron reemplazados por el controlador de forma segura y no por el código de llamada.

La cuenta de usuario utilizada por un administrador para realizar consultas no tendría esta función habilitada porque no utilizamos consultas parametrizadas al realizar la administración.

¿Esto funcionaría? ¿Se me escapa algo?

    
pregunta Sarel Botha 20.12.2012 - 19:45
fuente

4 respuestas

7

No hay DBMS que haga eso.

El problema principal es que no hay forma de que un servidor de base de datos diga qué partes de una consulta SQL se generaron a partir de la entrada del usuario, por lo que no hay manera de rechazar las consultas que se formaron con la entrada del usuario. Una vez que sus piezas se agregan a una cadena, no puede separarlas para averiguar qué fue lo que más.

Sin embargo, lo que quizás podría hacer un DBMS es observar que la mayoría de las fallas de inyección de SQL tienen la forma de valores literales:

"SELECT * FROM things WHERE id='"+id+"'"

y prohíbe esto al deshabilitar los literales (al menos cadenas e ints) de las consultas. Esto sería un poco inconveniente ya que ya no podría escribir consultas con literales estáticos en:

"SELECT * FROM things WHERE id=? AND active=1", id

en su lugar, tendría que usar un parámetro para todo:

"SELECT * FROM things WHERE id=? AND active=?", id, 1

Definitivamente, esta sería una característica interesante para un DBMS para introducir como una opción. Sin embargo, aún no detectaría la entrada de usuario utilizada para otros fines, por ejemplo, nombres de columna:

"SELECT * FROM things ORDER BY "+sortcolumn

que sucede más a menudo de lo que a uno le gustaría.

  

El protocolo de red de la base de datos debe tener la capacidad para que el controlador comunique que los parámetros en la consulta fueron reemplazados por el controlador de forma segura y no por el código de llamada.

O, mejor, use un protocolo que pase parámetros por separado al cuerpo de la consulta. Algunos DBMS y capas de acceso a datos hacen esto, otros no.

    
respondido por el bobince 20.12.2012 - 22:41
fuente
3

Sí, hay algo que te falta. A menos que también escriba la base de datos para no permitir nada, sino parametrizar dónde no funcionará la cláusula. ¿Cómo sabrá la base de datos cuando alguien está enviando solo una cadena de consulta o cuando algo se está parametrizando? ¿Qué pasa si el software simplemente pasa la consulta en sí, sin parámetros. es decir, su código utiliza:

sqlcommand = "Select * from users where userid = @id"
parameter p = new parameter(someId)
sqlcommand.parameters.add(p)

El controlador o lo que sea puede enviar esto a la base de datos como:

Select * from users where userid = 1234

    
respondido por el BlackICE 20.12.2012 - 20:40
fuente
3

Análisis de código estático

Hay una variante de tu idea que se usa en la práctica y funciona bastante bien según mi experiencia:

Las herramientas de análisis de código estático como Findbugs pueden identificar invocaciones de métodos de base de datos (por ejemplo, executeUpdate) con sentencias de SQL que no son constantes de tiempo de compilación.

No es perfecto a través de: Se perderán las invocaciones de los métodos de base de datos a través de la reflexión.

Problemas con el análisis después del hecho

SELECT * FROM sossys WHERE type = 2;

Podría ser una declaración codificada dura perfectamente fina. De acuerdo, se puede argumentar que los parámetros siempre deben usarse incluso para sentencias no dinámicas.

Suponga que la siguiente declaración se envía al servidor de base de datos

SELECT * FROM person, account 
WHERE account.person_id = person.id AND person.id=:1

Esta declaración se ve bien en una mirada rápida. Fue creado por un algoritmo de búsqueda que une dinámicamente las tablas relevantes. En este caso, se engañó para unirse a la tabla de la cuenta, lo que resultó en una exposición de los hashes de contraseña.

Debido a la naturaleza de SQL, no hay forma de usar sentencias de SQL estático para esto, a menos que el número de tablas opcionales sea muy pequeño. El enfoque de análisis de código estático creará una advertencia para activar la revisión manual.

Resumen

No tengo conocimiento de una base de datos o controlador que evite consultas creadas dinámicamente. Su enfoque no captará todo, pero probablemente detectará los errores comunes. Hasta que esté disponible, las herramientas de análisis de código estático son una muy buena opción para ir con.

    
respondido por el Hendrik Brummermann 20.12.2012 - 22:31
fuente
2

No por defecto.

Lo que puede hacer es deshabilitar el acceso directo de CRUD a cualquier tabla por parte de cualquier usuario no administrativo (como los inicios de sesión utilizados por sus sitios web y software) y, en su lugar, proporcionar acceso a las operaciones de CRUD otorgando permisos EXECUTE sobre procedimientos almacenados específicos. Esta es la "capa de servicio del hombre pobre"; no puede hacer nada excepto lo que permite un procedimiento almacenado, y esos procedimientos almacenados nunca deben tratar los datos de las variables de entrada como comandos en sí mismos. He visto esto muchas veces en la industria, a menudo evitando el modelo ORM más reciente.

Mencioné "capa de servicio"; esa es básicamente la otra forma de bloquear una base de datos contra ataques en general, al requerir que todas las solicitudes de datos pasen por una capa de servicio, que implementa las consultas reales de una manera impermeable a la inyección (como usar un ORM, que ejecuta la mayoría de las declaraciones a través de sp_executesql, que mantiene todos los parámetros pasados separados del comando real). Funciona de la misma manera básica que los procedimientos almacenados, excepto que ahora tiene una línea de seguridad adicional; nada en el lado del cliente o en el servidor web necesita saber cómo iniciar sesión en la base de datos.

    
respondido por el KeithS 20.12.2012 - 23:25
fuente

Lea otras preguntas en las etiquetas