如何在不使用cfqueryparam的情况下编码/转义varchar以更安全?我想实现相同的行为,而不使用<cfqueryparam>
来绕过"在这个RPC请求中提供了太多的参数。最大值是2100"的问题。参见:http://www.bennadel.com/blog/1112-Incoming-Tabular-Data-Stream-Remote-Procedure-Call-Is-Incorrect.htm
更新:
- 我想要验证/安全部分,而不生成准备语句。
- 我能对
<cfquery>
中的varchar做的最强编码/转义是什么? - 可能是类似
mysql_real_escape_string()
的东西?
正如其他人所说,与长度相关的错误起源于更深层次,而不是queryparam标记。它提供了一些有价值的保护,因此它的存在是有原因的。
你总是可以将这些值插入到一个临时表中,并与那个表连接,或者使用列表函数将这个大列表分成几个小列表,然后分别使用。
SELECT name ,
..... ,
createDate
FROM somewhere
WHERE (someColumn IN (a,b,c,d,e)
OR someColumn IN (f,g,h,i,j)
OR someColumn IN (.........));
cfqueryparam执行多个功能
-
验证数据类型。如果你输入integer,它会确保有整数,如果没有,它不允许传入
-
它将SQL脚本的数据从可执行代码中分离出来(这是防止SQL注入的地方)。
-
它在DB引擎级别创建绑定变量以帮助提高性能。
这就是我如何理解cfqueryparam工作。你有没有考虑过是打几个小电话还是打一个大电话?
这是安全问题。停止SQL注入
Adobe建议您在每个cfquery标记中使用cfqueryparam标记,以帮助保护数据库免受未经授权的用户的攻击。有关更多信息,请参阅安全公告ASB99-04,"动态查询中的多个SQL语句",网址为www.adobe.com/devnet/security/security_zone/asb99-04.html,以及ColdFusion开发人员指南中的"访问和检索数据"。
我要问自己的第一件事是"我是如何在一个查询中结束超过2100个参数的?"。因为这本身就应该是一个非常非常大的危险信号。
然而,如果你被困住了(要么是因为它超出了你的控制范围,要么是因为你的动机水平超出了你的解决;-),那么我会考虑:
- 前面提到的临时表的想法
- 对于超过一定长度的值,只需将它们切成两半,然后使用字符串连接器将它们重新连接在一起,例如:
SELECT *
FROM tbl
WHERE col IN ('a', ';DROP DATABAS'+'E all_my_data', 'good', 'etc' [...])
这有点可怕,但你的整个查询听起来很可怕,所以这可能不是一个问题。
参数值超过一定长度或有停止字或其他东西。这也是一个相当严峻的建议。
认真地回顾你的需求,看看是否有一种方法不需要2100+参数。你真正需要做的是什么?
问题不在于cfqueryparam,而在于MsSQL本身:
每个SQL批处理必须符合批处理大小限制:65,536 *网络数据包大小。
SQL Server查询的最大大小?在条款?有没有更好的方法
和
http://msdn.microsoft.com/en-us/library/ms143432.aspx有几次我遇到这个问题,我已经能够使用子选择和/或表连接重写查询。我建议尝试像这样重写查询,以避免参数max.
如果不可能重写(例如,所有多个参数都来自外部源),您将需要自己验证数据。为了执行安全验证,我使用了以下正则表达式:
<cfif ReFindNoCase("[^a-z0-9_ ,.]",arguments.InputText) IS NOT 0>
<cfthrow type="Application" message="Invalid characters detected">
</cfif>
如果在文本字符串中发现除逗号、下划线或句号以外的任何特殊字符,代码将强制执行错误。(您可能希望更清楚地处理这种情况,而不仅仅是抛出错误。)我建议您根据您正在验证的字段中预期或允许的值修改此值。如果您正在验证一个逗号分隔的整数字符串,您可以切换到使用更有限制的正则表达式,如"[^0-9 ,]"
,它只允许数字、逗号和空格。
这个答案不会转义字符,它首先不允许它们。它应该用于您不会与<cfqueryparam>
一起使用的任何数据。就我个人而言,我只在使用动态排序字段时才发现需要这样做;并不是所有的数据库都允许您在ORDER BY
子句中使用绑定变量。