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

11

我在使用ColdFusion编程,但尽可能保持在cfscript中。我有一个函数,允许我传入一个查询来执行它:

<cfquery blah > #query# </cfquery>

不过,当我使用如下构造我的查询语句sql = "SELECT * FROM a WHERE b='#c#'"并将其传入时,ColdFusion会将单引号替换为两个单引号。因此,在最终的查询语句中,它变成了 WHERE b=''c''

我已经尝试以多种不同的方式创建字符串,但无法使它仅保留一个引号。即使进行字符串替换也无效。

这是为什么呢?这破坏了我在整个项目中只使用cfscript的希望。

4个回答

18

ColdFusion在<cfquery>标签中插入变量时,会默认转义单引号。

如果你想要实现你的需求,你需要使用PreserveSingleQuotes()函数。

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

然而,这并未解决您面临的SQL注入危险。

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

阅读旧的Ben Forta专栏Brad Wood最近的一篇文章可以获取有关使用<cfqueryparam>的更多信息。


6

像其他人所说的那样,回答你的问题需要使用preserveSingleQuotes(...)

然而,你实际想要的解决方案并不是以这种方式动态构建查询。这是非常糟糕的做法。

将SQL放在cfquery标签中,并根据需要使用任何ifs/switches等,确保所有CF变量都使用cfqueryparam标签。

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


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)本质上只是对值进行“空操作”,将其转换为函数结果以绕过自动转义。

0

我投票支持Dave的答案,因为我认为他做得很好。

不过,我想补充一下,也有几种不同的工具专门为ColdFusion设计,可以简化你可能执行的许多常见SQL任务。有一个非常轻量级的工具叫做DataMgr,由Steve Bryant编写,还有Mark Mandel的Transfer,Doug Hughes最初创建的Reactor和我开发的DataFaucet。每个工具都有其自身的优点和缺点。个人认为,你应该考虑使用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注入攻击,并且插入、更新和删除语句也有类似的语法。(有几个简单规则可避免SQL注入。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接