使用存储过程访问数据可以带来哪些安全性好处?

时间:2009-01-07 18:51:31

标签: sql sql-server security stored-procedures

我见过一些建议,建议您通过存储过程分层所有数据访问来保护数据库。

我知道对于SQL Server,您可以保护表,甚至是针对CRUD操作的列。

例如:

 --// Logged in as 'sa'
 USE AdventureWorks;
 GRANT SELECT ON Person.Address(AddressID, AddressLine1) to Matt;
 GRANT UPDATE ON Person.Address(AddressLine1) to Matt;

 --// Logged in as 'Matt'
 SELECT * from Person.Address;                       --// Fail
 SELECT AddressID, AddressLine1 from Person.Address; --// Succeed
 UPDATE Person.Address SET AddressLine1 = '#____ 2700 Production Way' 
        WHERE AddressID = 497;                       --// Succeed

鉴于您可以针对CRUD操作保护表甚至列,使用存储过程如何提供额外的安全性或安全性管理?

9 个答案:

答案 0 :(得分:11)

因为通过限制对那些存储过程的所有访问,您已经建立了一个定义的数据库接口,通过该接口必须进行所有访问...因为您将对DENY'd Direct进行选择,插入,更新和删除操作表和视图,没有人可以直接编写他们自己的设计的sql,做他们想做的任何事情......如果你想限制插入到员工表中,员工被分配到三个以上的项目,只有那些有一个在熟练度测试中得分大于85,那么你可以将该约束写入SaveEmployee sproc,并让它向试图这样做的任何客户端代码抛出异常......

当然你可以使用客户端代码做同样的事情,但是使用sProcs使得这个过程更容易设计和管理,因为它只在一个地方,并且所有试图访问这个数据库系统的应用程序都必须符合任何要求您在SProcs中定义的约束和/或安全性规定...没有流氓开发人员编写一个新的单独客户端应用程序来访问数据库可以忽略或解决SProc中的约束或安全性规定,如果该SProc是插入的唯一方式或更新记录......

答案 1 :(得分:10)

您可能不想让Matt carte-blanc直接更新某些表或列。如果马特决定这样做会怎么样:

UPDATE Person.Address SET AddressLine1 = NULL

糟糕。 Matt忘记了WHERE子句并且只是管理了你的数据库。或者也许马特对他的老板很生气,并决定在一天结束时退出。或者也许Matt的密码不像以前那么安全,现在黑客就有了它。

这只是一个简单的例子。对表和列的控制可能会变得更加复杂,并且除了存储过程之外的其他任何操作都可能无法实现。

答案 2 :(得分:4)

存储过程允许用户执行CRUD操作(插入,更新,删除),但仅以有限的方式提供额外的安全性。例如,允许用户Matt更新某些行的地址而不更新其他行的地址。

它允许您添加数据检查以确保插入的数据是有效数据,而不是随机垃圾。对于大多数事情,您可以使用约束和/或触发器来完成某些工作,但是有一些限制。存储过程通过确保用户允许执行的操作来增强安全性。

通过应用程序控制的单点访问,而不是通过任意数量的接口,更容易跟踪数据库的更改。并且该过程可以更新审核日志。

答案 3 :(得分:2)

在SQL Server中,如果正确使用存储过程(这意味着没有动态SQl),则不必授予对表的任何直接访问权限。这意味着您的用户只能执行由procs定义的内容。如果您的数据库中有任何财务数据或敏感数据,则只有尽可能少的人(通常只有dbas)才能直接访问这些表。这严重降低了欺诈或心怀不满的员工诋毁您的业务关键数据或员工窃取个人信息以进行身份​​盗用的风险。在会计术语中,这是一个必要的内部控制,开发人员的便利性或个人希望从用户界面动态地完成所有事情应该被数据的不安全性所压倒。不幸的是,在很少的公司中,事实并非如此。大多数开发人员似乎只担心数据的外部威胁,但内部数据往往更为关键。

如果您在表级限制用户,然后用户触发查询以执行合法插入,则不会发生。如果您授予他们进行插入的权限,那么他们可以执行他们想要的任何adhoc插入,而不仅限于来自用户界面的插件。使用存储过程,它们只能执行proc特定的事情。

答案 4 :(得分:1)

在大多数(所有?)RDBMS中,您可以对特定用户的特定表进行“授权”访问。存储过程可以作为不同的用户运行,具有更大的访问权限。但是存储过程与提供对整个表的访问权限不同,相反它可以先检查一些内容,只返回符合您特定安全性问题的行。

您可以对视图执行类似的检查,但存储过程通常更灵活,因为它们几乎可以运行任何SQL - 比较结果并确定要返回的行。

答案 5 :(得分:0)

存储过程更好,因为存储过程(IIRC)的安全性将胜过表/列的安全性。

对于单表访问,这不是什么大问题。但是,如果您的操作涉及多个表上的多个列,则对表/列具有一个访问/拒绝标志可能不适用于所有情况。

但是,存储过程可以执行复合操作,您可以在该操作上适当地设置安全性。

答案 6 :(得分:0)

简单地说,它允许您在功能上而不是在结构上定义安全性。换句话说,它限制了允许用户执行的操作(具有更大的粒度),而不是可访问的数据库对象(以非常粗略的粒度)。

请注意,我们所说的是“由DBA控制的安全性”,而不是网站或系统管理员或软件模块,所有这些都是有用的,并且是整个安全基础架构的一部分。

答案 7 :(得分:0)

这里详细讨论的第一个好处是更好地控制权限 - 用户可以限制在特定的行中,而不仅仅是每列(在大型系统中管理的是btw); SP可以强制执行业务逻辑和事务逻辑;数据可能仅取决于其他数据(例如连接);更新可能一次限制为单行;等

其次,这可以为SQL注入提供额外的保护层(虽然它不完整和自动)。虽然这可能是SP内部的动态SQL,或者是错误的并置调用,SP会强制执行参数类型等等,将代码与数据分开。

第三,它归结为控制,在开发阶段 - 通常你已经训练过编写SP的DBA,而不是程序员(接受过代码培训......)

这更不用说非安全性好处,例如更好的性能。

答案 8 :(得分:0)

在存储过程中,您可以添加逻辑控件。如果某些内容不正确,您可以返回错误代码,而不是直接更新表数据。

例如,您有一个反馈系统。只有在管理员启动反馈活动后才能提交反馈。它只是更新某个表中的标志。 然后,当用户提交反馈时,SP可以检查是否设置了标志。

Select @IsFeedbackDefined = IsFeedbackDefined From sometable where ID = @ID

IF @IsFeedbackDefined is Null or @IsFeedbackDefined = false 
Begin
    Return -2   --can not submit feedback
End