¿Hay una longitud de campo que sea demasiado corta para permitir una inyección de SQL dañina?

51

Estaba leyendo sobre inyección SQL y vi esto, lo que me hizo pensar:

  

ingrese los campos lo más pequeños posible para reducir la probabilidad de que un pirata informático pueda meter el código SQL en el campo sin que sea truncado (lo que generalmente conduce a un error de sintaxis T-SQL).

Fuente: Desató Microsoft SQL Server 2008 R2

¿Cuál es el tamaño de campo más corto donde la inyección de SQL puede causar daño?

Con daños, la modificación de la base de datos o la devolución de resultados no pretendidos por el diseño. Incluir un marcador de comentario final ( -- ) en un campo de dos caracteres no causaría daño, solo causaría una consulta fallida. El pirata informático potencial, podría aprender que el campo es susceptible de inyección, pero no pueden aprovecharlo.

    
pregunta James Jenkins 28.02.2017 - 17:18
fuente

8 respuestas

85

No, no hay una longitud que sea demasiado corta para ser explotable (al menos en algunas situaciones).

Un filtro de longitud no es una protección válida contra la inyección de SQL, y las declaraciones preparadas realmente son la única defensa adecuada.

Sin embargo, un filtro de longitud es una buena medida como defensa en profundidad (como lo son los filtros enteros, los filtros alfanum, etc.). Hay muchas situaciones en las que, por ejemplo, la entrada válida nunca podría estar por encima de los 30 caracteres, pero donde una explotación significativa requiere más. Debería (pero probablemente no) ir sin decir que cualquier filtrado como defensa en profundidad debe tener lugar en el lado del servidor, ya que cualquier cosa del lado del cliente simplemente se puede pasar por alto.

Anulación de restricción

Las cláusulas de restricción (por ejemplo, AND / OR ) se pueden omitir con dos caracteres, lo que puede causar un daño real, no solo una consulta fallida. El ejemplo más simple es un inicio de sesión (otros ejemplos serían la eliminación no autorizada de datos adicionales):

SELECT * FROM users WHERE userid = [id] AND password = [password]

Inyección:

id = 1#
password = wrong_password

Carga útil: 2 caracteres

DoS

Los ataques DoS requieren muy pocos caracteres. En un ejemplo de MySQL, se necesitan 7 para la llamada real + x para los segundos dados + lo que sea necesario para poder llamar a la función y corregir la consulta.

Ejemplo:

SELECT * FROM users WHERE userid = [id]

Inyección (esta es una inyección válida, una forma más larga sería 1 AND sleep(99) ):

sleep(99)

Carga útil: 9 caracteres

Datos de lectura

Si se muestran los datos, la longitud depende principalmente de la tabla y el nombre de la columna. Asumiré un recuento de columnas igual para todas las tablas (puede suceder, y guarda caracteres).

Ejemplo:

SELECT * FROM comments WHERE commentid = [id]

Inyección:

1 union select * from users

Carga útil: 27 caracteres.

Edición de datos

Las modificaciones no autorizadas de la base de datos también se pueden lograr con pocos caracteres.

Ejemplo:

UPDATE users SET password = '[password]' WHERE id = [id]

Inyección (en contraseña):

',isadmin='1

Carga útil: 12 caracteres

Una omisión de restricción también funcionaría (el resultado es que todas las contraseñas están ahora vacías *):

'#

Carga útil: 2 caracteres

* El ejemplo de contraseña se usa por simplicidad; Las contraseñas deben estar con hash haciendo que el ejemplo sea imposible. El ejemplo aún se aplica en todas las situaciones similares (actualizar un nombre de usuario, actualizar permisos, etc.)

    
respondido por el tim 28.02.2017 - 19:10
fuente
89

Sin contexto, voy a suponer que el autor se refiere a los campos de entrada en una aplicación cliente. El ejemplo más fácil de usar sería un formulario en una página HTML en una aplicación web, aunque lo que voy a describir es efectivo para prácticamente cualquier tipo de aplicación cliente.

Dado este contexto, la respuesta es no, no hay una longitud máxima del campo de entrada lo suficientemente corta como para protegerlo de la inyección de SQL, porque no controla la longitud máxima del campo de entrada . El atacante lo hace. Cuando el formulario que contiene el campo de entrada vive en el cliente (como en una ventana del navegador en la máquina del atacante) está fuera del límite de confianza y está fuera de su control. Puede ser manipulado de cualquier manera que el atacante quiera o necesite, o puede evitarse por completo. Recuerde, para una aplicación web, todo lo que obtiene es una solicitud HTTP. No tiene idea de cómo se creó, y no hay razón para creer que todo lo que le pidió al navegador que sucedió, que se ejecutaron los controles de seguridad del lado del cliente, que cualquier cosa en la solicitud es tan tu intención o de cualquier forma segura.

Entonces, no, la longitud del campo de entrada no es un mecanismo válido de prevención de inyección de SQL, y nunca, nunca confíe en la entrada que cruza un límite de seguridad sin validarlo.

    
respondido por el Xander 28.02.2017 - 18:18
fuente
11
  

ingrese los campos lo más pequeños posible para reducir la probabilidad de que un pirata informático pueda meter el código SQL en el campo sin que sea truncado (lo que generalmente conduce a un error de sintaxis T-SQL).

En mi humilde opinión, esto es una mierda. Utilizar la longitud de los campos de entrada para proteger de la inyección SQL es un consejo terrible:

  • La única forma correcta de protegerse de la inyección de SQL es mediante el uso de una declaración preparada. Los datos de entrada son un parámetro de la consulta y nunca se utilizarán como texto SQL.
  • El tamaño de un campo debe controlarse lado del servidor porque nunca se puede confiar en lo que viene en una solicitud (podría ser falsa) y se debe usar para sanear los datos antes de usarlos en el negocio. almacenamiento de capa o base de datos.
  • El consejo de usar algo que no sea las mejores prácticas es confuso para los desarrolladores novatos.
respondido por el Serge Ballesta 28.02.2017 - 23:13
fuente
8

No.

Considere la consulta:

select * from tweets
WHERE RowNum >= [offset]
AND RowNum < [offset] + [limit]

Si pudiera inyectar un único no entero (por ejemplo, la letra "a") para offset , la consulta generará un error de sintaxis y ninguna publicación aparecerá con los "resultados no previstos por el diseño" Requisito para causar daños. Si puede inyectar una cadena vacía, obtendrá el mismo efecto con una carga útil de longitud cero. Inyectar un comentario final sería una pérdida de dos caracteres;)

Un atacante puede aprovechar esto en un ataque de denegación de servicio (a diferencia de un inundación de red generalmente asociado con DoS, sin embargo, sigue siendo un DoS ). Dependiendo del servicio denegado, esto podría ser catastrófico.

Como otras respuestas sugieren que la longitud del campo no tiene relación con el impacto de la inyección SQL. Las declaraciones preparadas y parametrizadas son el camino a seguir como se menciona en la Hoja de referencia de OWASP SQL Injection Prevention .

    
respondido por el benrifkah 28.02.2017 - 22:10
fuente
4

No.

Ejemplo simple de una inyección de SQL de un solo carácter:

'

Lanzaría un error que sería un ejemplo de "resultados devueltos que no fueron diseñados por el diseño". Muchas veces se pueden utilizar errores para obtener información que ayudará más adelante en una explotación.

    
respondido por el MikeSchem 01.03.2017 - 21:14
fuente
3

Sí.

La longitud máxima es cero. La única manera de hacer que la entrada no confiable sea segura a través de la longitud máxima, sin ninguna otra validación o verificación, es ignorar completamente la entrada que comienza en el índice 0.

Aquí hay muchas otras (mejores) respuestas, pero esta sirve para responder la pregunta teórica de cómo mantenerse seguro cuando la longitud del campo es la única herramienta a su disposición.

    
respondido por el Dan 02.03.2017 - 19:27
fuente
0

La longitud de un campo no tendrá nada que ver con la inyección de SQL, porque tal ataque funciona simplemente al comentar el código anterior e iniciar el código de ataque, por lo que la longitud de cualquier campo no afectará esta estrategia.

    
respondido por el Spencer Williams 03.03.2017 - 00:47
fuente
0

Hay mucha teoría aquí pero no hay ejemplos reales. Cuando encontré una vulnerabilidad de inyección de sql en el mundo real (ahora parcheada), intenté usar campos de entrada de alrededor de 30 caracteres. Esto fue muy frustrante, ya que me tomó un tiempo darme cuenta de que después de 30 caracteres se eliminó todo, y que 30 personajes no me dejaron espacio por mucho.

(muchos ejemplos de inyección de sql tienen un sql simple "como select * from table donde id = @id", el sql del mundo real generalmente será mucho más complicado)

Puede ser elegante con su entrada, y un experto en SQL probablemente podría usar algunos trucos para reducir el conteo de la carga útil. Pero no importa lo complicado que seas si quieres seleccionar un nombre largo de tabla, necesitarás muchos caracteres para eso.

De todos modos, cuando cambié a usar un campo de entrada con más de 1 k de caracteres, encontré esa cantidad suficiente para la inyección de SQL.

Dicho esto, como dicen muchos de los comentaristas que están por encima de mí, La mejor defensa contra la inyección de sql son las declaraciones preparadas

    
respondido por el Almenon 02.08.2018 - 17:38
fuente

Lea otras preguntas en las etiquetas