Entrada de desinfección para consultas parametrizadas

10

Si utilizo consultas totalmente parametrizadas en todas partes, ¿sigue siendo necesario y / o relevante para la seguridad sanear de alguna manera la entrada? P.ej. ¿Verifica que las direcciones de correo sean válidas antes de enviar una consulta parametrizada contra la base de datos, o filtrar ciertos caracteres especiales del texto?

Pienso en herramientas de terceros benignas, pero no tan bien diseñadas (tal vez scripts autoescritos por el administrador, o algunos CrystalReports elaborados por un no técnico) que intentan consumir datos no deseados de nuestra base de datos.

En este momento, tenemos soporte completo de Unicode contra SQL Server (MySQL parece tener problemas con Emojis), no estoy seguro de cómo filtrar los riesgos de seguridad sin perder esa propiedad.

    
pregunta Alexander 27.10.2017 - 13:09
fuente

3 respuestas

12

No, no es necesario. Pero por favor, sigue leyendo.

La entrada sanitización es un término horrible que pretende que puedes mover una varita mágica en los datos y convertirlos en "datos seguros". El problema es que la definición de "seguro" cambia cuando los datos son interpretados por diferentes piezas de software.

Los datos que pueden ser seguros para incrustarse en una consulta SQL pueden no ser seguros para incrustarlos en HTML. O JSON. O comandos de shell. O CSV. Y eliminar los valores (o rechazarlos directamente) para que sean seguros de incrustar en todos esos contextos (y muchos otros) es demasiado restrictivo.

Entonces, ¿qué debemos hacer? Asegúrese de que los datos nunca estén en condiciones de hacer daño.

La mejor manera de lograr esto es evitar la interpretación de los datos en primer lugar. Las consultas SQL parametrizadas son un excelente ejemplo de esto; los parámetros nunca se interpretan como SQL, simplemente se colocan en la base de datos como, bueno, datos.

Para muchas otras situaciones, los datos aún deben estar incrustados en otros formatos, por ejemplo, HTML. En ese caso, los datos deben escaparse para ese idioma en particular en el momento en que están incrustados. Por lo tanto, para evitar XSS, los datos se escapan de HTML en el momento de la visualización. No en el tiempo de entrada. Lo mismo se aplica a otras situaciones de incrustación.

Entonces, ¿deberíamos pasar todo lo que obtengamos directamente a la base de datos?

Tal vez. Depende.

Definitivamente, hay cosas que puedes consultar sobre la entrada del usuario, pero esto depende en gran medida del contexto. Debido a que el saneamiento está mal definido y es mal utilizado, prefiero llamar a esta validación .

  • Por ejemplo, si se supone que un campo es un entero, ciertamente puede validar este campo para asegurarse de que contiene un entero (o tal vez NULL).
  • Ciertamente, puede hacer alguna validación en los campos de correo electrónico (aunque algunas personas sostienen que no hay mucho que pueda hacer, además de verificar la presencia de @ , y tienen un buen punto).
  • Puede requerir que los comentarios tengan una longitud mínima y máxima.
  • Probablemente debería verificar que cualquier cadena contenga únicamente caracteres válidos para su codificación (por ejemplo, no hay secuencias UTF-8 no válidas).
  • Puede restringir un nombre de usuario a ciertos caracteres, si eso tiene sentido para su base de usuarios.
  • Una longitud mínima para las contraseñas es, por supuesto, increíblemente común.

Como puede ver, estas comprobaciones dependen mucho del contexto. Y todos ellos son para ayudar a aumentar las probabilidades de obtener datos que tengan sentido. No deben proteger su aplicación de entradas maliciosas (inyección de SQL, XSS, inyección de comandos, etc.), porque este no es el lugar para hacerlo.

Los usuarios deben tener la libertad de escribir '; DROP TABLE users; -- sin que su publicación sea rechazada o modificada a \'; DROP TABLE users; -- . Tenga en cuenta que puedo incluir dicho contenido "malicioso" en sec.SE!

Entonces, para responder a tu pregunta original:

  

... ¿sigue siendo necesario y / o relevante para la seguridad a fin de sanear la entrada?

No, no lo es. Pero, por favor, escape adecuadamente los datos donde sea necesario antes de enviarlos. Y considere las validaciones, cuando corresponda.

  

Pienso en herramientas de terceros benignas, pero no tan bien diseñadas (tal vez scripts autoescritos por el administrador, o algunos CrystalReports elaborados por un no técnico) que intentan consumir datos no deseados de nuestra base de datos.

Luego, escape o filtre los datos antes de enviarlos a esas herramientas, pero no mezcle datos en su base de datos.

Pero realmente, esos scripts deben ser arreglados o reescritos teniendo en cuenta la seguridad.

  

(MySQL parece tener problemas con Emojis)

Poco fuera de tema, pero eche un vistazo al conjunto de caracteres utfmb4 para MySQL;)

    
respondido por el marcelm 27.10.2017 - 19:02
fuente
8
  

Si utilizo consultas totalmente parametrizadas en todas partes, ¿sigue siendo necesario y / o relevante para la seguridad sanear de alguna manera la entrada?

Sí. Siempre es una buena idea limpiar la entrada antes de enviarla a la base de datos.

Las consultas parametrizadas podrían salvarlo de los ataques de inyección de SQL, pero podrían no ser beneficiosos en caso de ataques XSS almacenados. Si un usuario envía un código javascript malicioso a su formulario, lo almacena correctamente en su base de datos y muestra el mismo campo en otra parte, el script malicioso podría ejecutarse en el navegador de la víctima.

Siempre es una buena idea sanear la entrada antes de enviarla por adelantado, y limpiar la salida antes de enviarla al navegador del cliente.

EDITAR: Como se señaló en los comentarios, el saneamiento es diferente de los valores de codificación / escape. La desinfección, aquí, significa que las entradas se pueden validar para algunas verificaciones básicas antes de pasarlas a la base de datos (o cualquier otra capa). Por ejemplo, un campo que espera una dirección de correo electrónico se puede validar para una dirección de correo electrónico válida, un campo para la edad se puede validar solo para números enteros, etc. Las expresiones regulares resultan ser de gran ayuda aquí. Se debe tener en cuenta que estas comprobaciones deben colocarse tanto en la parte delantera (lado del cliente) como en la parte posterior.

En el caso de los campos que esperan texto enriquecido, puede implementar Política de seguridad de contenido en las páginas donde se mostrará la entrada del usuario. También puede usar un desinfectante HTML para sanear la entrada del usuario.

    
respondido por el pri 27.10.2017 - 13:15
fuente
2

Sí, siempre debe desinfectar los datos de entrada. El saneamiento no se trata solo de protegerlo de la inyección, sino también de validar tipos, valores restringidos (enums), rangos, etc. Mientras que un atacante podría no ser capaz de manipular su sql, todavía puede causar un comportamiento no deseado en el resto de tu solicitud.

Por ejemplo, si un atacante cambia un valor de enumeración, ¿podrían manipular el sistema? ¿Acaban de cambiar un rol, tipo de usuario, etc ...? Alternativamente, podrían ingresar un valor mayor al que puede ser aceptado en su esquema o en el tipo de datos (byte v int32, int64), esto podría causar que la aplicación se bloquee y expone información o deja datos huérfanos modificados (no tramitados).

    
respondido por el JonnySchnittger 27.10.2017 - 15:49
fuente

Lea otras preguntas en las etiquetas