提问人:Rekesoft 提问时间:10/20/2017 更新时间:10/20/2017 访问量:238
清理不可参数化 sql 的最佳方法
Best way of sanitize unparametrizable sql
问:
我必须将一个SQL字符串注入到数据库中,以便第三方读取它,执行它,并用结果制作报告。由于用户可以选择报表所需的列,以及重命名列,因此我以如下代码结束:
string sql = "SELECT ";
foreach(KeyValuePair<string, string> field in report.fields)
{
sql += "[" + field.Key + "] as [" + field.Value + "];
}
sql += " WHERE idrpt=@id";
我唯一可以参数化的查询部分是 WHERE 子句,但如果我在 Web 上的研究没有被误导,则无法参数化 SELECT 子句中的列名和别名。现在,鉴于我无法更改程序的工作方式(我必须向第三方生成有效的 SQL 查询才能执行它),清理输入字符串的最佳方法是什么?
我已经通过根据有效列列表检查列名来解决有关列名的部分,但我不能对别名这样做,别名可以是用户愿意提供的任何少于 80 个字符的字符串。
答:
1赞
Radim Bača
10/20/2017
#1
如您所指出的,无法参数化列名和别名。因此,你对 SQL 注入持开放态度。为了最大程度地减少问题,您可以使用 quotename,它类似于您当前使用的方法。
string sql = "SELECT ";
foreach(KeyValuePair<string, string> field in report.fields)
{
sql += "quotename(" + field.Key + ") as quotename(" + field.Value + ")";
}
sql += " WHERE idrpt=@id";
评论
0赞
Rekesoft
10/20/2017
是的,这就是我现在使用的方法。事实上,我正在使用 QUOTENAME(“ + 字段。Value.Replace(“'”, “''”) + “)”,但我仍然不确定。
1赞
Magisch
10/20/2017
#2
是的,所以你有一个无法更改的 SQL 布局,这需要你这样做。这很不幸,但让我们充分利用它。
正如您在评论中所说,您可能需要一些特殊字符支持,因此请专门转义这些特殊字符。
除此之外,您应该将允许的名称减少到字母数字字符,并可能减少空格。根据您选择的验证机制(例如正则表达式)验证这些字符,并仅允许这些字符。这可能会使您免受SQL注入的影响。
这不是最佳选择,但在这种情况下,这似乎是你能做的最好的事情。
评论