¿Es la confianza en las consultas parametrizadas la única forma de protegerse contra la inyección de SQL?

13

Todo lo que he visto sobre los ataques de inyección SQL parece sugerir que las consultas parametrizadas, en particular las de procedimientos almacenados, son la única forma de protegerse contra dichos ataques. Mientras trabajaba (en la Edad Oscura), los procedimientos almacenados se consideraban una práctica deficiente, principalmente porque se consideraban menos mantenibles; menos verificable altamente acoplado y bloqueó un sistema en un solo proveedor; ( esta pregunta cubre algunas otras razones).

Aunque cuando estaba trabajando, los proyectos prácticamente desconocían la posibilidad de tales ataques; Se adoptaron varias reglas para proteger la base de datos contra la corrupción de varios tipos. Estas reglas se pueden resumir en:

  1. Ningún cliente / aplicación tuvo acceso directo a las tablas de la base de datos.
  2. Todos los accesos a todas las tablas fueron a través de vistas (y todas las actualizaciones de las tablas base se realizaron a través de activadores).
  3. Todos los elementos de datos tenían un dominio especificado.
  4. No se permitió 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 permisos se configuraron de manera adecuada, por ejemplo, un rol restringido para que solo las vistas tengan derecho a cambiar los datos.

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

EDIT

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 Defensa contra ataques a los sistemas. Me parece que tanto las defensas más fundamentales son deseables, y pueden hacer que la dependencia de tales consultas no sea necesaria, o menos crítica, incluso para defenderse específicamente contra los ataques de inyección.

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

enlace

enlace

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

  1. Un extenso diccionario de datos, combinado con un extenso diccionario de datos de seguridad
  2. Generación de activadores, consultas y restricciones del diccionario de datos
  3. Minimiza el código y maximiza 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 a mi (s) pregunta (s) original (ahora se enfatiza en negrita).

    
pregunta Chris Walton 21.07.2011 - 12:21

3 respuestas

25

Los procedimientos almacenados no protegen automáticamente contra la inyección. ¿Qué 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 inyecciones, estén o no en proceso.

    
respondido por el Craig 21.07.2011 - 12:27
11
  

Entonces, ¿es un conjunto de reglas (impuestas) como esta una alternativa adecuada a los procedimientos almacenados para prevenir ataques de inyección SQL? Si no, ¿por qué 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 deben poder acceder a la base de datos a través de un rol restringido que solo tenga acceso SELECCIONAR, INSERTAR, ACTUALIZAR y BORRAR a aquellas tablas (y filas, cuando sea posible) a las que necesita acceso. Si desea asegurarse de que ningún cliente pueda enviar correo basura o eliminar todas las entradas, utilice 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 a un costo de rendimiento enorme, dependiendo de la eficiencia de las vistas. Es una complejidad innecesaria 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 tenía implicaciones que tenían a los DBA rechinando los dientes en ocasiones; pero se hizo cumplir.

Eso es simplemente un error. Si los desarrolladores no pueden manejar NULL s, tiene grandes problemas.

  

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

Usted no necesita procedimientos almacenados, simplemente use consultas parametrizadas con una función que escapa a los argumentos, como pg_query_params . Por supuesto, si su base de datos se puede escribir en todo el mundo o si el rol del cliente tiene acceso completo a todo, de todos modos, está jodido. Alguien tiene que venir y darse cuenta de lo que está haciendo el cliente, y luego cocinar un cliente en cinco minutos que destruye (o, lo que es peor, envenena) su DB.

    
respondido por el l0b0 21.07.2011 - 12:57
6

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

El primer problema es que usted declara 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 las reglas como éstas 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 necesita facilitar eso 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, por lo tanto, no le importa si los datos se han pasado de nuevo a través de la tabla vCustomers o Clientes subyacentes. Usted puede haberse protegido de algunas debilidades pero no de todas. Del mismo modo, si el cliente puede realizar las actualizaciones, incluso si se realizan a través de los desencadenantes, se puede escribir SQL para que active los desencadenantes y realice las actualizaciones.

(En términos de todas las actualizaciones que se realizan a través de los desencadenantes, voy a decir dos cosas: (1) cuando leí esto me puse un poco enfermo en la boca y (b) no te gustan los procedimientos almacenados porque son "menos mantenibles, menos comprobables, altamente acoplados, y bloquean un sistema en un solo proveedor", pero sí usa 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 de SQL (y no veo ninguna de estas reglas que lo impidan) y el atacante está dentro. Es posible que encuentren una base de datos muy poco intuitiva detrás de ellas, pero si están determinado que solo los ralentizará en lugar de detenerlos).

La otra cosa aquí es que también estás agregando complejidad y (así como la sobrecarga que genera), la complejidad tiende a generar agujeros que pueden explotarse.

No estoy diciendo que no se pueda crear un conjunto de reglas de este tipo. ¿Por qué más te molestas? Parecen más engorrosos y menos confiables que los simples métodos aceptados para prevenir este tipo de ataque.

    
respondido por el Jon Hopkins 21.07.2011 - 14:00

Lea otras preguntas en las etiquetas