存储过程是否有助于消除SQL注入/存储过程相对于应用程序中的正常SQL语句有什么好处?

时间:2009-07-23 19:39:45

标签: sql database stored-procedures

我对SQL世界很陌生。以下是我的问题:

  • 在应用程序中存储过程优于普通SQL语句有什么好处?
  • 存储过程是否有助于消除SQL注入?
  • 在Microsoft SQL Server中,它称为存储过程。在Oracle,MySQL,DB2等中怎么样?

感谢您的解释。

5 个答案:

答案 0 :(得分:7)

只有直接存储过程,如果以参数化方式调用它们,则会阻止SQL注入。如果你的应用程序中仍然有一个带有过程名称的字符串,并且在用户输入中将参数连接到代码中的字符串,那么你仍然会遇到麻烦。

但是,当单独使用时,存储过程允许您添加一些额外的保护,使您可以禁用除EXEC命令之外的所有内容的权限。除此之外,参数化查询/预处理语句通常由服务器缓存,因此几乎在所有方面都像存储过程一样。

尽管如此,存储过程对于大型企业来说有两大优势:

  • 它们允许您为数据库定义应用程序接口,以便可以在多个应用程序之间共享系统,而无需在这些应用程序中复制逻辑。
  • 他们将sql代码移动到db,在那里您可以轻松地进行经验丰富的DBA调优,更新和维护,而不是通常不知道他们正在使用数据库代码做什么的应用程序开发人员。 / LI>

当然,这些优势并非没有代价:

  • 跟踪源代码管理中的更改更加困难
  • 数据库代码与使用它的代码分开很远
  • 用于管理许多存储过程的开发人员工具不太理想(如果您曾经在管理工作室中打开存储过程文件夹来查找数据库的200个过程,那么您知道我在这里谈论的内容)。

答案 1 :(得分:6)

使用存储过程时我考虑的一些好处

  • 存储过程将查询代码封装在服务器上,而不是在应用程序内部。这使您可以对查询进行更改,而无需重新编译应用程序。
  • 存储过程可用于更明确的应用程序安全性。您可以拒绝基表的所有权限,仅在procs上授予执行权限。这为您提供了更小的安全足迹来管理。
  • 存储过程是编译代码。使用最新版本的MSSQL,服务器可以更好地存储执行计划 - 所以这不像以前那么大,但仍需要考虑
  • 只有正确使用时,存储过程才能消除SQL注入风险。确保在存储过程中以正确的方式使用参数 - 存储的过程只是在它们内部执行连接的动态SQL,对任何人都没有好处。

答案 2 :(得分:2)

在大多数情况下,使用存储过程,SQL注入的可能性要小得多。虽然有时您希望传递一些存储过程需要在存储过程中使用动态SQL的数据,然后您就回到了开始的位置。从这个意义上说,我认为在支持它们的编程语言中使用参数化查询没有任何优势。

我个人讨厌存储过程。在两个脱节的地方拥有代码是一个痛苦的屁股,它使部署更加复杂。我不主张用SQL语句乱丢你的代码,但这会导致它自己的一系列麻烦。

我建议使用以下两种方式之一实现DAL层。

  1. 我的最爱,使用一个物体 关系管理系统(ORM)。 我一直在使用nHibernate 而且我非常喜欢它。该 学习曲线陡峭但是 绝对值得我的回报 意见。
  2. 某种保持机制 所有SQL代码都放在一个地方。 某种查询库 你选择或真的 结构化的一组类 为您设计SQL。我不 推荐这种方式,因为它 基本上就像建立自己的ORM 你可能没有时间 正确地做到了。
  3. 忘记存储过程。使用ORM。

答案 3 :(得分:0)

存储过程允许您将sql代码存储在应用程序之外的位置。这使您能够:

  • 更改SQL代码而不重新编译/重新分发应用程序
  • 让多个应用程序使用相同的存储过程来访问相同的数据。
  • 限制用户直接访问数据库中的表读/写。
  • 从开发的角度来看,它还允许DBA /数据库程序员处理sql代码,而无需通过应用程序代码来处理它。 (基本上分离责任)。

存储过程是否可以防止注入攻击?多半是对的。在sql server中,您可以创建对此无效的存储过程,主要是使用sp_executesql。现在这并不是主要的sp_executesql是一个安全漏洞,它只是意味着在使用它时需要采取更多的预防措施。

这并不意味着存储过程是防止这种情况的唯一方法。您可以使用parameritized sql来完成防止sql注入的相同任务。

我同意其他人的存储过程可能很麻烦,但他们也有自己的优势。在我工作的地方,由于各种原因,我们可能有20个不同的生产数据库(不要问)。我工作的可能是三个子集,我的队友和我知道这三个真的非常好。存储过程如何帮助我们?人们来找我们,当他们需要从这些数据库中获取信息时,我们可以为他们获取信息。我们不必花费数小时来解释模式以及哪些数据被去规范化。它是一个抽象层,它允许我们针对我们所知道的数据库编写最有效的代码。如果您不是这种情况,那么可能存储过程不是可行的方法,但在某些情况下,它们可以添加很多价值。

答案 4 :(得分:0)

存储过程(不使用动态SQL的过程)可以使整个应用程序更安全的一种方法是,您现在可以在存储过程级别而不是在表级别设置权限。如果你以这种方式访问​​所有数据(并且禁止动态sql!),这意味着用户在任何情况下都不能对不在存储过程中的数据库做任何事情。开发人员总是想说他们的应用程序代码可以抵御外部威胁,但是他们似乎忘记了内部威胁通常要严重得多,并且通过允许表级别的权限,他们受任何能够找到方法的用户的支配直接在应用程序外查询数据库(另一个原因是,在大型商店中,最多只有两三个人对数据库中的任何内容都拥有生产权限,这限制了谁可以窃取信息)。

任何使用除存储过程之外的任何财务系统的内部欺诈都是完全开放的,这是违反内部控制的行为,应该防止欺诈并且不会通过良好的审计。