我在ColdFusion中编码,但是试图保留在cfscript中,所以我有一个函数允许我传入一个查询来运行它
<cfquery blah >
#query#
</cfquery>
但不知何故,当我使用sql = "SELECT * FROM a WHERE b='#c#'"
构建查询并将其传入时,ColdFusion已将单引号替换为2个单引号。因此它在最终查询中变为 WHERE b=''c''
。
我尝试过很多不同的方法来创建字符串,但我不能只留下一个引用。即使进行字符串替换也没有效果。
知道为什么会这样吗?在这个项目期间,它破坏了我在cfscript中生活的希望
答案 0 :(得分:18)
根据设计,ColdFusion在<cfquery>
标记内插入变量时会转义单引号。
要做你想做的事,你需要使用PreserveSingleQuotes()
功能。
<cfquery ...>#PreserveSingleQuotes(query)#</cfquery>
但是,这并没有解决您自己暴露的SQL注入的危险。
使用<cfqueryparam>
还允许您的数据库缓存查询,这在大多数情况下会提高性能。
有关使用<cfqueryparam>
的好处的详细信息,请阅读an old Ben Forta column和a 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)
我想补充说,还有一些为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。)