How to override SQL sanitization in ColdFusion
Asked Answered
D

3

5

I have the unfortunate task of cleaning up a bunch of old ColdFusion code. Queries are all over the place, I am working on moving them all to common CFCs for easier maintenance.

I am running into a problem because cfquery is automatically converting the single quotes to double-single-quotes. How can I override that behavior?

More specific information is below.


So here is the query I started with:

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

The weird thing here is that a literal is being "selected", because of the way we want it displayed (again, I didn't write this, I'm just trying to clean it up a little). So in the common function, there is an optional parameter for the select clause:

  <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>

Here is the problem: When I pass in "GroupName AS LastName, '[Group]' AS FirstName" for the strSelectAttributes parameter, the query that is sent to the database is:

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

You see, my quotes got "sanitized" into an invalid query.

Disassembly answered 2/6, 2009 at 15:43 Comment(1)
See also #267086Neutralism
L
17

ColdFusion does not escape all single quotes, but only those that arrive in the query through variable interpolation. This is the offender:

SELECT #Arguments.strSelectAttributes#

This is usually a helpful thing and a small line of defense against SQL injection attacks. So rule number one is (here and everywhere else): Don't build your SQL string from variables.

If you positively have to use variables to build an SQL string, despite all the possible negative effects, use the PreserveSingleQuotes() function:

SELECT #PreserveSingleQuotes(Arguments.strSelectAttributes)#

This function stops ColdFusion from auto-escaping the single quotes.

And any other function call does the same thing, by the way. Try:

SELECT #LCase(Arguments.strSelectAttributes)#

which means that PreserveSingleQuotes() is really just a no-op that turns a string into a function result, preventing the automatic variable interpolation routine from happening.

Lonely answered 2/6, 2009 at 15:52 Comment(0)
M
7

Put a call to preserveSingleQuotes() around your variable. It's made specifically for writing dynamic SQL. Also, you really, really should use cfqueryparam for your values, and I hope you're sanitizing your input somehow so that arguments.strSelectAttributes can't contain something like ';drop table groups; in it.

<cfquery name="getObjectInfo" datasource="#Application.DataSource#">
  SELECT #preserveSingleQuotes(Arguments.strSelectAttributes)#
  FROM   Groups
  WHERE  Group_ID = <cfqueryparam value="#Arguments.intGroupID#" cfsqltype="cf_sql_integer"/>
</cfquery>
Mistress answered 2/6, 2009 at 16:0 Comment(3)
thanks. i'm aware of sql injection, but in my case the parameter is only coming from code we control, never from a user.Disassembly
I wouldn't use "it's only called by code we control" as the justification for writing a DAO class that is otherwise vulnerable to SQL injection.Geraint
SQL Injection isn't the only reason to use query bind params. It also allows your DB to pre-compile the query, making it run faster.Mistress
P
-3

If you really wanting to clean up the code step two is converting that spaghetti into stored procedures.

Planck answered 17/7, 2009 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.