防御与插入SQL注入攻击

时间:2011-10-25 20:43:26

标签: c# sql sql-server oracle

所以我们有一个自定义记录器(真的想使用Log4Net,就这种情况不适用)。从配置文件中,您可以配置要插入的表的名称。

我正在参数化insert语句,但可配置的表名将用于insert语句,它是攻击的潜在向量。以下是将要构建的语句示例:

"insert into " + theTableName + " (static column list) values(parameterized list of values)"

所以我的插入值是参数化的,非常安全,它是可能包含恶意内容的表名。

我的问题是,我可以做些什么来消毒表名?我认为攻击者注入的代码的性质必须与花园种类略有不同。 - 而不是勾号,你可能会用“table name()values()来关闭语句;做坏事 -

(或者类似的东西,我想)。为此,我正在考虑检查“;”和“ - ”。

有人能建议更好的消毒方法吗? (这将与Oracle和SQL服务器一起使用)

5 个答案:

答案 0 :(得分:2)

这仍然不能让你免受UNION攻击(以及其他几个)。如果你知道什么是允许的,最好做一些白名单检查拉丁字母或类似。

要检查的其他字符是

()`"'

和空白。

答案 1 :(得分:1)

我认为你有一个更大的问题,那就是用户可以指定一个语法安全且有效的表名,而这个名称在数据库中根本不存在。

因此,我会这样做:

  1. 加载配置文件时,只构建一次INSERT字符串(包括表名)。

  2. 通过检查系统元数据来确认当时的表名,以确保它是真实有效的表。

  3. 此时您可以警告用户日志记录已关闭,因为数据库中不存在表“theTableName”。

答案 2 :(得分:1)

为什么不将theTableID数字ID值用于存储表名theTableName的行。您可以将此数字ID值存储在用户PC上的配置文件中,并将其传递给应用程序。然后,您可以通过参数化查询查找它,然后将实际的字符串表名称连接到查询中。那将是安全的。

答案 3 :(得分:1)

对我来说,显而易见的解决方案是首先使用静态SQL验证您将在动态SQL中使用的表名:

select * from sys.tables where name = @thetablename

由于此查询绑定变量而不是连接变量,因此它应该不受SQL注入的影响。如果查询返回记录,则继续,否则将其作为错误处理。

答案 4 :(得分:0)

我想主要的问题是为什么theTableName变量甚至暴露给使用日志记录所针对的页面的人。

除此之外,通过查询系统目录中的表名并将它们转储到数组中并将其转换为.Contains(theTableName),白名单要么针对一组值设置,要么针对您在运行中创建的集合进行检查。在数组或任何等效的选择语言可能是最安全的方式。