sql - ColdFusion Query-Protección de inyección
sql-injection cfml (3)
Hago esta pregunta con cierta vergüenza porque debería saber la respuesta. ¿Podría alguien ser amable y explicar si y cómo la inyección podría ocurrir en el siguiente código?
<cfquery>
select * from tableName
where fieldName = ''#value#''
</cfquery>
Tengo especial curiosidad por los intentos de inyección y otras entradas maliciosas, no por las mejores prácticas o la validación de entrada para manejar la entrada de usuario "normal". Veo gente que aboga fuertemente por el uso de CFQueryParam, pero no creo que vea el punto. Si la entrada del usuario ha sido validada por coherencia con el esquema de la base de datos (p. Ej., Para que la entrada sea numérica para los campos numéricos de la base de datos), ¿se gana algo más utilizando CFQueryParam? ¿Qué hace <cfqueryparam CFSQLType = "CF_SQL_VARCHAR">
hacer eso ''#value#''
no funciona?
Para responder la primera parte de su pregunta, establezca su variable #value#
en lo siguiente:
someValue''; DELETE FROM tableName WHERE ''1'' = ''1
daría lugar a esta consulta que se ejecuta:
<cfquery>
select * from tableName
where fieldName = ''someValue''; DELETE FROM tableName WHERE ''1'' = ''1''
</cfquery>
¿CF ya no hace "mágicamente" esto en la etiqueta de consulta CF cuando ajusta las variables evaluadas en comillas simples?
Sí, se convertirá en ''''
para ti.
Ahora adivina qué SQL obtienes de este código:
<cfset value = "/'; DROP TABLE tableName -- " />
<cfquery>
select * from tableName
where fieldName = ''#value#''
</cfquery>
La etiqueta cfqueryparam funciona; el uso de params de consulta resuelve la inyección de SQL.
Cualquier intento escrito personalizado de validar, desinfectar o escapar (todas las cosas por separado, por cierto) son, en el mejor de los casos, tan buenas como el conocimiento del desarrollador del sistema de base de datos contra el que se ejecuta el código.
Si el desarrollador no tiene conocimiento de otros métodos de escape, o si los valores se modifican entre validación / escape y se procesan en SQL, o incluso si la base de código se transfiere a otro sistema de base de datos y parece estar bien, existe la posibilidad de un código personalizado rompiendo
Cuando se trata de seguridad, no quieres posibilidades como esa. Entonces usa cfqueryparam.
Actualizar:
Si bien esto responde a una parte de su pregunta, la respuesta de Peter es mejor, ya que aborda directamente su pregunta de "¿Por qué utilizar cfqueryparam, cuando CF automáticamente agrega protección escapando comillas simples?". Respuesta: En resumen, porque este último no siempre funciona. Las variables de vinculación lo hacen.
Dice en los documentos "escapa variables de cadena entre comillas simples", pero CF ya no hace "mágicamente" esto en la etiqueta de consulta CF cuando ajusta variables evaluadas en comillas simples?
Sí, la mayoría de las versiones escapan automáticamente de las comillas simples como medida de protección para quienes no usan cfqueryparam. Sin embargo, como señaló Scott anteriormente, es mejor usar cfqueryparam (es decir, variables de enlace) porque aseguran que los parámetros no se ejecuten como comandos sql . Las variables de vinculación funcionan, incluso en los casos en que el escape automático no funciona, como lo demuestra la respuesta de Peter .
Dicho esto, la protección de inyección sql es realmente solo un efecto secundario del uso de variables de vinculación. La razón principal para usar variables de vinculación es el rendimiento. Las variables de vinculación alientan a las bases de datos a reutilizar los planes de consulta , en lugar de crear un nuevo plan cada vez que cambie # su parámetro #. Eso reduce el tiempo de compilación, mejorando el rendimiento.
Cfqueryparam también tiene una serie de otros beneficios:
- Proporciona verificación de tipo de datos (longitud, valor, tipo, ...)
- Proporciona atributos que simplifican el manejo de "listas" y valores
null
- Realiza la comprobación del tipo de datos antes de que se envíe cualquier sql a la base de datos, lo que evita el desperdicio de llamadas a la base de datos
Si bien en realidad no se aplica a las columnas de cadenas, IMO otra gran razón para usarlo es la precisión. Cuando pasa una cadena entre comillas a la base de datos, confía en la conversión implícita . Básicamente, lo dejas en la base de datos para descubrir la mejor forma de realizar la comparación y los resultados no son siempre lo que esperabas. (Las cadenas de fecha son un excelente ejemplo). Puede terminar con resultados inexactos o, en ocasiones, consultas más lentas, según cómo la base de datos decida ejecutar el sql. Usar cfqueryparam evita esos problemas al eliminar la ambigüedad.