清理不可参数化的最佳方法 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 子句,但如果我在网络上的研究没有被误导,则无法参数化 SELECT 子句中的列名和别名.现在,鉴于我无法更改程序的工作方式(我必须向第三方生成有效的 SQL 查询才能执行它),清理输入字符串的最佳方法是什么?

我已经通过对照有效列列表检查列名解决了有关列名的部分,但我不能对别名执行此操作,别名可以是用户愿意使用的少于 80 个字符的任何字符串给。

如您所述,无法参数化列名和别名。因此,你是开放给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";

是的,所以您有一个无法更改的 SQL 布局,因此您必须这样做。这很不幸,但让我们充分利用它。

如您在评论中所述,您可能需要一些 特殊字符支持,因此请特别转义这些特殊字符。

除此之外,您应该将允许的名称减少为字母数字字符和可能的空格。根据您选择的验证机制(例如正则表达式)验证这些,并且只允许那些字符。这可能会让你远离 SQL 注射。

这不是最佳选择,但似乎是您在这种情况下可以做的最好的选择。