让我们说一下 MySQL 数据库(如果重要的话)。
7 回答
只有始终使用参数化查询,您才能免受 SQL 注入的影响。如果您在任何地方都使用适当的转义,您几乎不会受到 SQL 注入的影响(但是转义例程中可能存在并且已经存在错误,因此它不像参数那样万无一失)。
如果您调用存储过程,通过连接添加参数,我仍然可以在输入字段之一的末尾添加一个随机查询 - 例如,如果您有 CALL CheckLogin @username='$username', @password=' $password',$-things 代表直接连接的变量,没有什么能阻止我将 $password 变量更改为“'; DROP DATABASE; --”。
显然,如果您事先清理输入,这也有助于防止 SQL 注入,但这可能会过滤掉不应该清理的数据。
不,你不会完全安全。正如其他人所提到的,参数化查询总是要走的路——无论您如何访问数据库。
这有点像一个都市传说,使用 procs 你是安全的。我认为人们产生这种错觉的原因是因为大多数人认为您将使用代码中的参数化查询来调用 procs。但是,如果您不这样做,例如,如果您执行以下操作,那么您就会敞开心扉:
SqlCommand cmd = new SqlCommand("exec @myProc " + paramValue, con);
cmd.ExecuteNonQuery();
因为您使用的是来自最终用户的未过滤内容。再一次,他们所要做的就是终止线路(“;”),添加他们的危险命令,然后繁荣 - 你被冲洗了。
(顺便说一句,如果您在网络上,请不要从浏览器的查询字符串中获取未经过滤的垃圾信息——这使得对您的数据做极其糟糕的事情变得非常容易。)
如果您将查询参数化,您的状态会好得多。但是,正如这里的其他人所提到的,如果您的 proc 仍在生成动态 SQL 并执行它,则可能仍然存在问题。
我应该注意我不是反程序。Procs 对于解决数据访问的某些问题非常有帮助。但是 procs并不是SQL 注入的“灵丹妙药”。
这取决于你的存储过程做什么。如果他们根据参数动态生成 SQL,然后执行该 SQL,那么您仍然容易受到攻击。否则,你很有可能会好起来——但我不愿听起来 100% 自信!
不。如果您正在构建调用存储过程的 SQL,那么您仍然是目标。
您应该在客户端创建参数化查询。
不,因为您仍然可以在存储过程中使用 D-SQL ......并且在任何情况下验证和限制您的输入都是一个好主意。
存储过程不是保证,因为实际上易受攻击的是任何动态代码,包括存储过程中的代码和动态生成的对存储过程的调用。
只要不使用任意输入来生成代码,参数化查询和使用参数调用的存储过程都不会受到注入的影响。请注意,有很多动态代码也不容易受到注入(例如动态代码中的整数参数)。
然而,在很大程度上(我不确定 100% 是否真的有可能)存储基于 procs 的架构的好处是,对于客户端的动态代码,注入甚至可以在一定程度上得到防御(但不是完美的),因为:
只有 EXEC 权限被授予应用程序正在连接的任何用户上下文,因此任何 SELECT、INSERT、UPDATE、DELETE 查询都将失败。当然,无论如何都不应该允许 DROP 等。因此,任何注入都必须采用 EXEC 的形式,因此最终,只有您在 SP 层中定义的操作才能被注入(而不是任意 SQL)。
将数据库服务定义为一组存储过程(如软件中的任何抽象层)的许多其他好处包括在不影响应用程序的情况下重构底层数据库的能力,更好地理解和监控数据库中使用模式的能力分析器,以及在数据库中选择性优化而无需部署新客户端的能力。
此外,考虑使用细粒度的数据库访问(通常也称为基于角色的访问控制)您的数据库的主要用户应该具有完成其工作所需的权限,而不是其他权限。安装后不需要创建新表吗?撤销该权限。没有以 sysdba 身份运行的合法需要?那就不要!如果未授予用户该权限,则指示用户“删除数据库”的偷偷摸摸的注入将被阻止。那么您需要担心的只是数据泄漏的 SELECT 语句。