ColdFusion在字符串中构造数据库查询时添加额外的引号

时间:2008-11-05 20:43:13

标签: sql string coldfusion railo cfml

我在ColdFusion中编码,但是试图保留在cfscript中,所以我有一个函数允许我传入一个查询来运行它 <cfquery blah > #query# </cfquery>

但不知何故,当我使用sql = "SELECT * FROM a WHERE b='#c#'"构建查询并将其传入时,ColdFusion已将单引号替换为2个单引号。因此它在最终查询中变为 WHERE b=''c''

我尝试过很多不同的方法来创建字符串,但我不能只留下一个引用。即使进行字符串替换也没有效果。

知道为什么会这样吗?在这个项目期间,它破坏了我在cfscript中生活的希望

4 个答案:

答案 0 :(得分:18)

根据设计,ColdFusion在<cfquery>标记内插入变量时会转义单引号。

要做你想做的事,你需要使用PreserveSingleQuotes()功能。

<cfquery ...>#PreserveSingleQuotes(query)#</cfquery>

但是,这并没有解决您自己暴露的SQL注入的危险。

使用<cfqueryparam>还允许您的数据库缓存查询,这在大多数情况下会提高性能。

有关使用<cfqueryparam>的好处的详细信息,请阅读an old Ben Forta columna recent post by Brad Wood可能会有所帮助。

答案 1 :(得分:6)

正如其他人所说,你的问题的答案正在使用preserveSingleQuotes(...)

但是,您真正想要的解决方案而不是以这种方式动态构建您的查询。这是坏坏。

将您的SQL置于cfquery标记内,并根据需要使用任何ifs / switch / etc,并确保所有 CF变量使用cfqueryparam标记。

(注意,如果在ORDER BY子句中使用变量,则需要手动转义任何变量;不能在ORDER BY子句中使用cfqueryparam)

答案 2 :(得分:4)

使用以下语法时,ColdFusion会自动转义<cfquery>标记中的单引号:

SELECT * FROM TABLE WHERE Foo='#Foo#'

如果您想在#Foo#中保留单引号,则必须致电#PreserveSingleQuotes(Foo)#

请注意,自动转义仅适用于变量值,而不适用于功能结果。

SELECT * FROM TABLE WHERE Foo='#LCase(Foo)#' /* Single quotes are retained! */

从这个角度来看,函数PreserveSingleQuotes()(参见Adobe LiveDocs)不仅仅是对值的“空操作” - 将其转换为绕过自动转义的函数结果。

答案 3 :(得分:0)

自从我认为他做得很好以来,我投了Dave的答案。

我想补充说,还有一些为ColdFusion设计的不同工具可以简化许多您可能执行的常见SQL任务。有一个非常轻量级的工具,名叫DataMgr,由Steve Bryant编写,以及Transfer来自Mark Mandel,Reactor最初是由Doug Hughes创建的,我开发的是{{3} }}。每个都有自己的优点和缺点。就个人而言,我认为你很容易认为DataFaucet能够为你提供最好的cfscript能力,并提供各种语法来构建不同类型的查询。

以下是一些例子:

qry = datasource.select_avg_price_as_avgprice_from_products(); //(requires CF8)

qry = datasource.select("avg(price) as avgprice","products"); 

qry = datasource.getSelect("avg(price) as  avgprice","products").filter("categoryid",url.categoryid).execute();

qry = datasource.getSelect(table="products",orderby="productname").filter("categoryid",url.categoryid).execute();


该框架确保cfqueryparam始终与这些过滤器语句一起使用以防止sql注入攻击,并且插入,更新和删除语句也有类似的语法。 (有几个DataFaucet。)