2009-06-02 12 views
5

Tengo la desafortunada tarea de limpiar un montón de código ColdFusion anterior. Las consultas están por todos lados, estoy trabajando en moverlas todas a CFC comunes para un mantenimiento más fácil.Cómo anular la desinfección de SQL en ColdFusion

Me encuentro con un problema porque cfquery convierte automáticamente las comillas simples en comillas dobles. ¿Cómo puedo anular ese comportamiento?

Más información específica está por debajo.


Así que aquí es la consulta Empecé con:

<cfquery name="getObjectInfo" datasource="#BaseDS#"> 
    SELECT groupName AS lastname, '[Group]' AS firstname 
    FROM groups 
    WHERE groups.group_id = #objectreference_id# 
</cfquery> 

Lo extraño aquí es que un literal está siendo "seleccionados", debido a la forma en que queremos que se muestre (de nuevo, yo no No escriba esto, solo estoy tratando de limpiarlo un poco). Así que en la función común, no es un parámetro opcional para la cláusula select:

<cffunction name="fSelGroup" access="public" returntype="query" 
       hint="Returns query selecting given group."> 

    <cfargument name="intGroupID" type="numeric" required="true" 
       hint="ID of group to be returned." /> 
    <cfargument name="strSelectAttributes" type="string" required="false" 
       hint="Attributes to be selected in query" 
       default="*" /> 

    <cfquery name="getObjectInfo" datasource="#Application.DataSource#"> 
     SELECT #Arguments.strSelectAttributes# 
     FROM Groups 
     WHERE Group_ID = #Arguments.intGroupID# 
    </cfquery> 

    <cfreturn getObjectInfo /> 

    </cffunction> 

Aquí está el problema: Cuando paso en "GroupName AS LastName, '[Group]' AS FirstName" para el parámetro strSelectAttributes, la consulta que se envía a la base de datos es:

SELECT GroupName AS LastName, ''[Group]'' AS FirstName 
FROM Groups 
WHERE Group_ID = 4 

Verá, mis citas se "desinfectaron" en una consulta no válida.

+0

Ver también http: // stackoverflow.com/questions/266586/coldfusion-adding-extra-quotes-when-constructing-database-queries-in-strings – ale

Respuesta

17

ColdFusion no escapa todos comillas simples, pero solo aquellos que llegan a la consulta mediante interpolación variable. Este es el delincuente:

SELECT #Arguments.strSelectAttributes# 

Esto suele ser una cosa útil y una pequeña línea de defensa contra los ataques de inyección SQL. Así que la regla número uno es (aquí y en todas partes): no construyas tu cadena SQL a partir de variables.

Si positivamente tiene que variables de utilizar para construir una cadena SQL, a pesar de todos los posibles efectos negativos, utilice la función PreserveSingleQuotes():

SELECT #PreserveSingleQuotes(Arguments.strSelectAttributes)# 

Esta función para ColdFusion de auto-escapar de las comillas simples.

Y cualquier otra llamada de función hace lo mismo, por cierto. Proveedores:

SELECT #LCase(Arguments.strSelectAttributes)# 

lo que significa que PreserveSingleQuotes() es en realidad un no-op que convierte una cadena en un resultado de la función, la prevención de la rutina automática de la interpolación de variables suceda.

+0

+1 Muy bueno saberlo. –

7

Llamar a preserveSingleQuotes() alrededor de su variable. Está hecho específicamente para escribir SQL dinámico. Además, realmente debería usar cfqueryparam para sus valores, y espero que esté desinfectando su entrada de alguna manera para que arguments.strSelectAttributes no contenga algo como '; drop table groups; en eso.

<cfquery name="getObjectInfo" datasource="#Application.DataSource#"> 
    SELECT #preserveSingleQuotes(Arguments.strSelectAttributes)# 
    FROM Groups 
    WHERE Group_ID = <cfqueryparam value="#Arguments.intGroupID#" cfsqltype="cf_sql_integer"/> 
</cfquery> 
+0

gracias. Soy consciente de la inyección sql, pero en mi caso el parámetro solo proviene del código que controlamos, nunca de un usuario. – Kip

+4

No utilizaría "solo es llamado por el código que controlamos" como la justificación para escribir una clase DAO que de otra manera sería vulnerable a la inyección SQL. –

+1

La inyección SQL no es la única razón para usar parámetros de vinculación de consulta. También le permite a su BD precompilar la consulta, lo que hace que se ejecute más rápido. –

-3

Si realmente quiere limpiar el código, el paso dos es convertir ese espagueti en procedimientos almacenados.

Cuestiones relacionadas