5

我有清理一堆旧的 ColdFusion 代码的不幸任务。查询无处不在,我正在努力将它们全部转移到常见的 CFC 以便于维护。

我遇到了一个问题,因为cfquery它会自动将单引号转换为双单引号。我怎样才能覆盖这种行为?

更具体的信息如下。


所以这是我开始的查询:

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

这里奇怪的是,一个文字被“选择”了,因为我们希望它显示的方式(同样,我没有写这个,我只是想把它清理一下)。所以在普通函数中,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>

这是问题:当我传入"GroupName AS LastName, '[Group]' AS FirstName"strSelectAttributes 参数时,发送到数据库的查询是:

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

你看,我的报价被“清理”成无效的查询。

4

3 回答 3

17

ColdFusion 不会转义所有单引号,而只会转义那些通过变量插值到达查询的单引号。这是罪犯:

SELECT #Arguments.strSelectAttributes#

这通常是一件有用的事情,也是抵御 SQL 注入攻击的一小道防线。所以第一条规则是(这里和其他地方):不要从变量构建你的 SQL 字符串。

如果您确实必须使用变量来构建 SQL 字符串,尽管有所有可能的负面影响,请使用以下PreserveSingleQuotes()函数:

SELECT #PreserveSingleQuotes(Arguments.strSelectAttributes)#

此函数阻止 ColdFusion 自动转义单引号。

顺便说一句,任何其他函数调用都会做同样的事情。尝试:

SELECT #LCase(Arguments.strSelectAttributes)#

这意味着 PreserveSingleQuotes() 实际上只是一个将字符串转换为函数结果的空操作,从而防止发生自动变量插值例程。

于 2009-06-02T15:52:53.723 回答
7

在您的变量周围调用 preserveSingleQuotes()。它专门用于编写动态 SQL。另外,你真的,真的应该使用 cfqueryparam 作为你的值,我希望你以某种方式清理你的输入,以便 arguments.strSelectAttributes 不能包含类似 ';drop table groups; 在里面。

<cfquery name="getObjectInfo" datasource="#Application.DataSource#">
  SELECT #preserveSingleQuotes(Arguments.strSelectAttributes)#
  FROM   Groups
  WHERE  Group_ID = <cfqueryparam value="#Arguments.intGroupID#" cfsqltype="cf_sql_integer"/>
</cfquery>
于 2009-06-02T16:00:03.787 回答
-3

如果您真的想清理代码,第二步是将意大利面条转换为存储过程。

于 2009-07-17T15:52:39.367 回答