如果我使用存储过程,我是否可以免于SQL注入?

时间:2008-10-27 13:39:08

标签: database security stored-procedures sql-injection

让我们说MySQL数据库(如果重要的话)。

7 个答案:

答案 0 :(得分:17)

如果您坚持使用参数化查询,那么您只能免于SQL注入。如果你在任何地方都使用适当的转义,你几乎 它们在转义例程中可能存在错误,因此它不像参数那样万无一失。

如果你调用存储过程,通过连接添加参数,我仍然可以在其中一个输入字段的末尾添加一个随机查询 - 例如,如果你有CALL CheckLogin @username ='$ username',@ password ='$ password',$ -things表示直接连接的变量,没有什么能阻止我将$ password变量更改为“'; DROP DATABASE; - ”。

显然,如果事先清理输入,这也有助于防止SQL注入,但这可能会过滤掉不应该清理的数据。

答案 1 :(得分:17)

不,你不会完全安全。正如其他人所提到的,无论你如何访问数据库,参数化查询总是可行的。

这是一个城市传说,有了触发你是安全的。我认为人们处于这种错觉之中的原因是因为大多数人都认为你将使用代码中的参数化查询调用procs。但是如果你不这样做,例如你做了类似下面的事情,那么你就是敞开心扉:

SqlCommand cmd = new SqlCommand("exec @myProc " + paramValue, con);
cmd.ExecuteNonQuery();

因为您正在使用最终用户的未经过滤的内容。再次,他们所要做的就是终止线路(“;”),添加他们的危险命令,然后繁荣 - 你就被冲洗了。

(顺便说一句,如果你在网上,不要从浏览器的查询字符串中获取未经过滤的垃圾 - 这会让你的数据做得非常糟糕。)

如果您对查询进行参数化,那么您的形状会更好。但是,正如其他人提到的,如果你的proc仍在生成动态SQL并执行它,那么可能仍有问题。

我应该注意到我不是反过程。过程对于解决数据访问的某些问题非常有帮助。但是,procs 是SQL注入的银弹解决方案。

答案 2 :(得分:8)

这取决于您的存储过程的作用。如果他们根据参数动态生成SQL,然后执行该SQL,那么您仍然容易受到攻击。否则,你很可能会很好 - 但我毫不犹豫地发出100%的自信!

答案 3 :(得分:6)

没了。如果您正在构建调用存储过程的SQL,那么您仍然是目标。

您应该在客户端创建参数化查询。

答案 4 :(得分:4)

不,因为你仍然可以在你的存储过程中使用D-SQL ......在任何情况下验证和限制你的输入都是个好主意。

答案 5 :(得分:3)

存储过程不是保证,因为实际上易受攻击的是任何动态代码,包括存储过程中的代码和动态生成的对存储过程的调用。

参数化查询和使用参数调用的存储过程只要不使用任意输入生成代码,就不会受到注入攻击。请注意,有很多动态代码也不易受注入攻击(例如动态代码中的整数参数)。

然而,基于存储过程的架构在很大程度上(我不确定100%是否真的可能)的好处是注入甚至可以在某种程度上防止(但不是完美)对于客户端的动态代码,因为:

只有EXEC权限被授予应用程序连接的任何用户上下文,因此任何SELECT,INSERT,UPDATE,DELETE查询都将失败。当然,不管怎么说都不应该允许DROP等。因此,任何注入都必须采用EXEC的形式,因此最终,只有您在SP层中定义的操作甚至可用于注入(而不是任意SQL)。

将数据库服务定义为一组存储过程(如软件中的任何抽象层)的许多其他好处包括能够在不影响应用程序的情况下重构数据库,更好地理解和监视使用模式的能力。您的数据库具有分析器,并且能够在数据库中有选择地进行优化,而无需部署新客户端。

答案 6 :(得分:3)

此外,请考虑使用细粒度数据库访问(通常也称为基于角色的访问控制)数据库的主要用户应该具有完成其工作所需的权限,而不是其他任何权限。安装后不需要创建新表吗?撤消该许可。没有合法的需要以sysdba身份运行?那就不要了!如果用户未被授予该权限,那么指示用户“DROP DATABASE”的偷偷摸摸注入将受到阻碍。然后,您需要担心的是数据泄漏的SELECT语句。