存储过程与触发器是Sql Server进行数据库开发与管理经常使用的两个对象,但是如果对存储过程与触发器的权限设置不当,则会给数据库带来巨大的安全隐患,抑或是MS就是这么设计的,是本人杞人忧天。
本文测试环境:sql server2005。
首先,建立测试环境
建立测试数据库 create database test
在测试数据库中建立两张表
create table t1(id int ,name varchar(10))
create table t2(id int ,name varchar(10))
向t2表中插入一行数据
insert into t2
select 1,'trieagle'
建立sql身份验证的登陆账号 trieagle ,同时test数据库中建立用trieagle
一、存储过程
情景说明:如果某用户拥有创建和执行存储过程的权限,则该用户可以建立一个存储过程,在该存储过程操作其他表中的数据。那么即使该用户对其他表没有操作权限,则调用该存储过程,可以对其他表中的数据进行操作。
1、为trieagle用户授予创建存储过程的权限以及执行存储过程的权限
grant create proc to trieagle
注意:trieagle用户要创建存储过程的话,可能还需要修改schema的权限
grant alter on schema :: dbo to trieagle
2、trieagle建立存储过程
Create proc p1
as
select * from t2
3、向trieagle用户赋予执行p1存储过程的权限
grant exec on p1 to trieagle
4、trieagle执行p1存储过程
Exec P1
结果
Id name
1 trieagle
成功的查看到t2表中的数据。
安全隐患在于:如果用户能够执行、修改存储过程的话,那么实际上你的数据库中的数据是出于一种既不安全的状态。
解决方法:如果该允许某个用户创建存储过程的话,让该用户在其自己的schema上来创建,这样可以避免上述问题。即:
管理员:grant create schema to trieagle
用户:create schema trieagle
Go
Create proc trieagle.p1
as
select * from t2
go
Exec trieagle.P1
结果:
消息229,级别14,状态5,过程p1,第3 行
拒绝了对对象't2' (数据库'test',架构'dbo')的SELECT 权限。
同样的情况在oracle上也存在,oracle的解释是:执行者执行存储过程时,会使用存储过程设计者所具有的权限,但是可以使用authid current_user指定用户运行存储过程时使用的权限。Sql server中有类似的语句是 在execute as ,但使用方法还未学习,例如:
create proc p1
with execute as 'trieagle'
as
select * from t2
二、触发器
情景说明:如果某用户拥有修改表的权限以及向表中有(insert、update、delete)权限之一的话,则该用户即可创建触发器。那么该用户在触发器中可以查看其他表的数据,甚至插入、修改、删除其他表的数据,即使该用户对其他表没有任何的操作权限。
一、建立测试环境
为trieagle用户授予向t1插入数据的权限,以及修改t1的权限
grant alter on t1 to trieagle
grant insert on t1 to trieagle
注意,在此并没有为trieagle用户赋予t2表的任何权限
二、trieagle用户创建触发器
create trigger t_query_t2
on t1
for insert
as
select * from t2
三、trieagle向t1表中插入数据
insert into t1 select 2,'wang'
观察结果,你会发现,会成功显示t2表中的数据。结果:
Id name
trieagle
安全隐患在于:如果用户能够创建触发器,并且在该表上有insert、update、delete权限之一的话,则实际上你的数据库中的数据是出于一种不安全的状态。
跟楼主的观点相反。我认为存储过程恰恰是DBA控制数据权限的最最强大的工具。用存储过程来控制权限,那表达能力可远超过什么select update delete之类的授权。
例如用户UserA下建立一个工资表Salar。对于用户UserB可以给员工涨工资,但他的官可能比较下,每次只能给用户甲一百元。对于用户UserC是的大领导,他可以给大家的工资加个0.这情况下在数据库层面上,用授权语句显然不能结果问题,存储过程就排上用场了。
首先,授权用户UserB和UserC对UserA.Salar有select权限,但禁止其update,delete。
在UserA下建立存储过程ProAdd100 为salar表中的工资加100;
授予UserB执行Proadd100的权利;
在UserA下建立存储过程ProMulti10 为salar表工资乘10;
授予UserC执行Promulti10的权限。
这样不就可以随心所欲的控制数据的权限了。多强大。
DBA杀手........
在mssql中,存储过程中引用了其它的存储过程可以不存在,这也是一个小隐患
这有什么隐患呢。如果是程序直接访问数据库,还可能访问不存在的表呢。这也是隐患吗。条条大路通罗马。关键不在走哪条路,关键在于质量。异常处理是必须的。