¿La dependencia de las consultas parametrizadas es la única forma de protegerse contra la inyección de SQL?

13

Todo lo que he visto en los ataques de inyección SQL parece sugerir que las consultas parametrizadas, particularmente las de procedimientos almacenados, son la única forma de protegerse contra tales ataques. Mientras trabajaba (en la Edad Media), los procedimientos almacenados eran vistos como una mala práctica, principalmente porque eran vistos como menos mantenibles; menos comprobable muy acoplado y bloqueó un sistema en un proveedor; ( Esta pregunta cubre algunas otras razones).

Aunque cuando estaba trabajando, los proyectos prácticamente ignoraban la posibilidad de tales ataques; Se adoptaron varias reglas para proteger la base de datos contra la corrupción de diversos tipos. Estas reglas pueden resumirse como:

  1. Ningún cliente / aplicación tenía acceso directo a las tablas de la base de datos.
  2. Todos los accesos a todas las tablas se realizaron a través de vistas (y todas las actualizaciones de las tablas base se realizaron mediante disparadores).
  3. Todos los elementos de datos tenían un dominio especificado.
  4. No se permitía que ningún elemento de datos fuera anulable; esto tenía implicaciones que tenían a los DBA rechinando los dientes en ocasiones; pero se hizo cumplir.
  5. Los roles y los permisos se configuraron de manera adecuada; por ejemplo, un rol restringido para otorgar solo a las vistas el derecho de cambiar los datos.

Entonces, ¿es un conjunto de reglas (forzadas) como esta (aunque no necesariamente este conjunto particular) una alternativa apropiada a las consultas parametrizadas para prevenir ataques de inyección SQL? ¿Si no, porque no? ¿Se puede proteger una base de datos contra tales ataques mediante medidas específicas (solo) de la base de datos?

EDITAR

El énfasis de la pregunta cambió ligeramente, a la luz de las respuestas iniciales recibidas. Pregunta base sin cambios.

EDIT2

El enfoque de confiar en consultas paramaterizadas parece ser solo un paso periférico en la defensa contra los ataques a los sistemas. Me parece que las defensas más fundamentales son deseables, y pueden hacer que depender de tales consultas no sea necesario, o menos crítico, incluso para defenderse específicamente contra los ataques de inyección.

El enfoque implícito en mi pregunta se basó en "armar" la base de datos y no tenía idea de si era una opción viable. La investigación adicional ha sugerido que existen tales enfoques. He encontrado las siguientes fuentes que proporcionan algunos consejos para este tipo de enfoque:

http://database-programmer.blogspot.com

http://thehelsinkideclaration.blogspot.com

Las características principales que he tomado de estas fuentes son:

  1. Un amplio diccionario de datos, combinado con un amplio diccionario de datos de seguridad
  2. Generación de disparadores, consultas y restricciones a partir del diccionario de datos.
  3. Minimice el código y maximice los datos

Si bien las respuestas que he tenido hasta ahora son muy útiles y señalan las dificultades que surgen al ignorar las consultas paramaterizadas, en última instancia, no responden mis preguntas originales (ahora enfatizadas en negrita).

Chris Walton
fuente
No compro los argumentos en contra de los procedimientos almacenados. Simplemente no son ciertas.
Konrad Rudolph
¿Qué pasa con el requisito de nulos?
Mark Canlas
2
@Konrad Rudolph: si escribe su aplicación en MySQL y luego decide migrar a DB2, ¿realmente cree que los procedimientos almacenados serán compatibles? Del mismo modo, si desea migrar a SQLLite? Además, suponga que actualiza su sistema operativo: si sus procedimientos almacenados se compilan en C (que están en DB2), probablemente todos necesitarán recompilarse. Estos son argumentos razonables, no absolutos, sino razonables.
Matthew Flynn
@Matthew Duh. En realidad estaba pensando en "consultas parametrizadas" al leer eso y comentar al respecto. Procedimiento almacenado = toda otra historia.
Konrad Rudolph

Respuestas:

25

Los procedimientos almacenados no protegen automáticamente contra la inyección. Que hay de esto

CREATE PROC proc
  @id VARCHAR(5)
AS
BEGIN
  EXEC("SELECT * FROM Client WHERE ClientId = " + @id);
END

El uso de consultas parametrizadas lo protegerá contra la inyección, ya sea que estén en proceso o no.

Craig
fuente
Gracias por centrarse en las consultas parametrizadas, en lugar de los procesos. Sin embargo, pregunto si la base de datos puede protegerse mediante métodos distintos de tales consultas, en particular métodos que se limitan solo a la capa de base de datos.
Chris Walton
1
+1 Además de eso, me gustaría afirmar que los procesos almacenados se consideran en su mayoría seguros porque es la única forma de evitar que los usuarios accedan directamente a las tablas, manteniendo una forma de recuperar los datos. Es la única forma de garantizar privilegios basados ​​en filas y columnas cuando el usuario necesita tener acceso directo a la base de datos con su cliente sin nada intermedio.
Falcon
2
@ Chris - Creo que lo que dice Craig aquí es que no puedes asumir que los procedimientos realmente te protegen. Quizás no sea una respuesta completa, más una corrección de la suposición en el título.
Jon Hopkins
@ Jon - He alterado el título de la pregunta e hice algunas modificaciones a la pregunta, a la luz de la corrección de Craig. No estaba al tanto de la suposición que estaba haciendo en la pregunta, hasta que comencé a recibir respuestas.
Chris Walton
2
Para reforzar lo que Craig escribe arriba, consulte databasesecurity.com/dbsec/lateral-sql-injection.pdf , "Inyección lateral de SQL: una nueva clase de vulnerabilidad en Oracle"
Bruce Ediger
11

Entonces, ¿es un conjunto de reglas (forzadas) como esta una alternativa apropiada a los procedimientos almacenados para prevenir ataques de inyección SQL? ¿Si no, porque no?

No, porque infligen una fuerte penalización a los desarrolladores. Un desglose por artículo:

1. Ningún cliente / aplicación tuvo acceso directo a las tablas de la base de datos.

Usa roles. Los clientes solo deberían poder acceder a la base de datos a través de un rol restringido que solo tiene acceso de SELECCIONAR, INSERTAR, ACTUALIZAR y ELIMINAR a esas tablas (y filas, cuando sea posible) a las que necesita acceso. Si desea asegurarse de que ningún cliente pueda enviar spam o eliminar todas las entradas, use una API para modificar los datos.

2. Todos los accesos a todas las tablas fueron a través de vistas.

Eso podría ser desde insignificante hasta un enorme costo de rendimiento, dependiendo de la eficiencia de las vistas. Es una complejidad innecesaria lo que ralentiza el desarrollo. Usa roles.

3. Todos los elementos de datos tenían un dominio especificado.

Podría ser mucho trabajo mantener, y probablemente debería normalizarse en una tabla separada.

4. No se permitió que ningún elemento de datos fuera anulable; esto tuvo implicaciones que ocasionaron que los DBA rechinaran los dientes en ocasiones; pero se hizo cumplir.

Eso es simplemente incorrecto. Si los desarrolladores no pueden manejar NULLs, tiene grandes problemas.

¿Se puede proteger una base de datos contra tales ataques mediante medidas específicas (solo) de la base de datos?

Usted no necesita procedimientos almacenados, sólo tiene que utilizar consultas parametrizadas con una función que se escapa de los argumentos, como pg_query_params . Por supuesto, si su base de datos es de escritura mundial o el rol del cliente tiene acceso completo a todo, está jodido de todos modos. Alguien solo tiene que venir y darse cuenta de lo que está haciendo el cliente, y luego preparar un cliente en cinco minutos que destruya (o peor aún, envenene) su DB.

l0b0
fuente
1
Dominio: en.wikipedia.org/wiki/Data_domain
Dan McGrath
+1 para roles. Contribuyen de manera importante a esto: no incluí roles en mi pregunta, pero fueron parte de la configuración; en particular, a las vistas se les asignó un rol restringido, como el que sugiere para los clientes. Punto tomado en el éxito de rendimiento de las vistas. Los dominios incluyeron pruebas de validación, principalmente rangos y longitud. Sus comentarios sobre la regla de anulación de datos son mucho más educados que algunos que escuché sobre esta regla. No dije explícitamente que los permisos se establecerían adecuadamente, aunque esta fue mi suposición.
Chris Walton
6

No estoy seguro de que tus reglas te protejan por completo.

El primer problema es que declaras que se aplican pero, además de tener una sobrecarga significativa, nunca he visto una aplicación perfecta.

En segundo lugar, mi lectura de ellos es que reglas como estas pueden hacer que las cosas sean más difíciles de explotar, pero no lo impiden. Por ejemplo, no tener acceso directo a las tablas en realidad no cambia mucho si las vistas le permiten acceder a los mismos datos. Si el cliente necesita hacer algo, una vista debe facilitarlo y si una vista lo facilita, un atacante puede utilizar la misma funcionalidad / datos.

Recuerde también que no se trata solo de actualizar o eliminar datos. Parte de la vulnerabilidad con la inyección de SQL es la recopilación de información y para eso no le importa si los datos se han devuelto a través de la vista vCustomers o la tabla subyacente Clientes. Es posible que se haya protegido de algunas debilidades, pero no de todas. Del mismo modo, si el cliente puede realizar las actualizaciones, incluso a través de disparadores, se puede escribir SQL para disparar los disparadores y realizar actualizaciones.

(En términos de todas las actualizaciones que se realizan a través de disparadores, voy a decir dos cosas: (1) cuando leí esto me enfermé un poco y (b) no te gustan los procedimientos almacenados porque ' re "menos mantenible; menos comprobable; altamente acoplado; y bloqueó un sistema en un solo proveedor", pero sí utiliza desencadenantes sobre los que básicamente se pueden decir las mismas cosas).

Todo lo que necesita es un agujero que permita la ejecución de sentencias SQL (y no veo ninguna de estas reglas que lo impida) y el atacante está dentro. Pueden estar encontrando una base de datos muy poco intuitiva detrás de ellos, pero si se determina que eso lo hará solo frenarlos en lugar de detenerlos).

La otra cosa aquí es que también está agregando complejidad y (además de la sobrecarga que crea), la complejidad tiende a conducir a agujeros que pueden ser explotados.

No estoy diciendo que tal conjunto de reglas no se pueda crear, más ¿por qué te molestarías? Parecen más engorrosos y menos confiables que simplemente seguir los métodos ampliamente aceptados para prevenir este tipo de ataque.

Jon Hopkins
fuente
+1 por comprender mi consulta real a la luz de mis suposiciones implícitas e inconscientes, y por responder adecuadamente. En cuanto a por qué uno podría molestarse, estoy trabajando en un proyecto donde gran parte del código se generará a partir de una descripción relevante de la arquitectura, y parte de esta arquitectura describe cómo generar rutinas de acceso a la base de datos. Todavía está abierto en cuanto a qué forma tomarán estas rutinas generadas.
Chris Walton