【发布时间】:2017-06-29 07:46:16
【问题描述】:
我可以在网上找到很多关于动态创建参数化查询的正确和安全方法的信息。但是这样的网站只讨论 where 子句的参数化。
那么,sql 语句的其他子句呢?请参阅以下内容:
string sql = string.Format(@"
SELECT MIN(TableName) as TableName, {0}
FROM
(
SELECT 'Table A' as TableName, {0}
FROM {1}
UNION ALL
SELECT 'Table B' as TableName, {0}
FROM {2}
) tmp
GROUP BY {0}
HAVING COUNT(*) = 1", columnList, tableA, tableB);
我正在构建一个语句,其中已对以下内容进行了参数化:
- select 子句中的项目
- from 子句中的表名
问题: 这对可能造成一些损害的 sql 注入有多脆弱?
无论如何,我想不出恶意黑客可以注入 sql,从而生成格式正确、可执行的 sql。不过话说回来,我不是 sql 专家。
【问题讨论】:
-
只要查询的任何部分来自不受信任的来源,它就容易受到 SQL 注入攻击。例如,如果您在
tableA = someBool ? "foo" : "bar";上方有某行代码,则没有风险,因为它将是 foo 或 bar。但是,如果您从某些表单提交或您无法控制的其他外部来源获得tableA的值,那么您就有风险了。查询中使用的其他变量也是如此。 -
使用参数化查询,推荐方法
-
@EhsanSajjad sql 参数不能用于表名和列名。
-
其他 cmets 出现了,但只是为了扮演魔鬼的拥护者,假设有人可以让您的代码以
columnList = "null from myTable; drop table myTable; ..."的值执行,而其余的 sql 是否是无关紧要的垃圾与否。如果引擎被告知要运行它直到它失败,你可能会遇到问题。 -
那是更正问题,不是愚蠢的问题! :) 答案是“也许”。在将变量传递给“查询构建器”之前,您确实必须自己确定变量如何分配其值。如果最终用户甚至其他开发人员可以操纵这些值,您应该通过清理输入来保护自己。如果你要清理输入,参数化查询就是这样做的方法。这完全取决于您的具体情况以及最终可能进入查询的值。
标签: c# sql sql-injection