sql-server - 授予数据库用户有限访问执行权限的后果是什么?

标签 sql-server database security stored-procedures

如果我有一个只有有限权限的用户 - 只有 db_datareader 和 db_datawriter,这应该只允许用户查询数据和插入/编辑/删除数据,不允许用户添加/修改/删除数据库中的表.

用户可能需要能够执行存储过程。如果用户被授予执行权限(通过以下 sql:“GRANT EXECUTE T​​O UserName”),之前的限制(datareader 和 datawriter)是否仍然对用户尝试通过存储过程执行的内容强制执行?还是执行权限真的打开了一个充满其他安全漏洞的潘多拉魔盒(如果是的话,是什么)?

最佳答案

如果存储过程的所有者有权对表进行选择、插入、更新或删除,那么只要调用者对存储过程具有执行权限,存储过程中的选择、插入、更新和删除语句就会执行过程,即使调用者没有直接对表执行选择、插入、更新或删除的权限。

但是,即使存储过程的所有者具有 DDL 权限,除非调用者具有执行 DDL 的权限,否则存储过程不能执行 DDL。请注意,这也适用于截断表。

回答:在您的情况下,向用户授予 db_datareaderdb_datawriter 已经为用户提供了所有表的完整 DML。授予对任何存储过程的执行权不会授予任何额外的权利。

通过提供所有外部程序必须通过的门,存储过程可用于提高数据完整性。不要授予插入、删除或更新权限,而是创建 SP 来执行这些工作并执行有关数据的适当规则。 (超出约束所能完成的范围。)正如 Joe Kuemerle 指出的那样,存储过程可用于提高安全性。

我在 SQL Server 2000 上开发应用程序时观察到这种行为,甚至在 SQL Server 2008 上重新测试并发现了相同的行为。我无法找到有关此行为的文档。

登录为 DBO 和 SA 创建表:

create table dbo.SO (PK int identity constraint SO_PK primary key
    , SomeData varchar(1000)
)

然后为基本 DML 创建一些存储过程:

create procedure dbo.InsertSO (@SomeData varchar(1000)) as
    begin
    insert into dbo.SO (SomeData) values (@SomeData)
    return SCOPE_IDENTITY()
    end
go

create procedure dbo.SelectSO (@PK int=null) as
    begin
    if @PK is not null
        select PK, SomeData from dbo.SO where PK = @PK
    else
        select PK, SomeData from dbo.SO
    end
go

create procedure dbo.CountSO as
    begin
    select COUNT(*) as CountSO from SO
    end
go

create procedure dbo.DeleteSO (@PK int=null ) as
    begin
    if @PK is not null
        delete dbo.SO where PK = @PK
    else
        delete dbo.SO
    end
go

create procedure dbo.UpdateSO (@PK int, @NewSomeData varchar(1000)) as
    begin`
    update dbo.SO
    set SomeData =  @NewSomeData
    where PK = @PK
    end
go

create procedure dbo.TruncateSO as
    begin
    truncate table dbo.SO
    end
go

作为 dbo,我们可以运行以下 SQL 语句:

declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()

declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()

insert into dbo.SO (SomeData) values ('Four score and seven years ago...')

select PK, SomeData
from dbo.SO

delete dbo.so
where PK = @PK_to_delete

update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update

select PK, SomeData
from dbo.SO

truncate table dbo.SO

select COUNT(*) as CountSO from dbo.SO

或者通过存储过程做同样的事情

go
declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'

declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'

exec dbo.InsertSO 'Four score and seven years ago...'

exec dbo.SelectSO 

exec dbo.DeleteSO @PK_to_delete

exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'

exec dbo.SelectSO

exec dbo.TruncateSO

exec dbo.CountSO

现在,创建一个 DDL 存储过程并进行测试:

create procedure dbo.DropSO as
    begin 
    drop table dbo.SO
    end
go
begin transaction
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
exec dbo.DropSO
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
rollback transaction

现在创建另一个用户并授予对所有存储过程的执行权限。不要授予任何其他权利。 (假设 public 没有额外的权限和混合模式身份验证。不建议使用混合模式身份验证,但可以更轻松地测试如何处理权限。)

exec sp_addlogin @loginame =  'SoLogin' , @passwd = 'notsecure', @defdb = 'Scratch'

exec sp_adduser @loginame = 'SoLogin', @name_in_db = 'SoUser'
go
grant execute on dbo.InsertSo to SoUser 
grant execute on dbo.InsertSO to SoUser
grant execute on dbo.SelectSO to SoUser
grant execute on dbo.CountSO to SoUser
grant execute on dbo.DeleteSO to SoUser
grant execute on dbo.UpdateSO to SoUser
grant execute on dbo.TruncateSO to SoUser
grant execute on dbo.DropSO to SoUser

以 SoLogin 身份登录。尝试 DML:

declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()

declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()

insert into dbo.SO (SomeData) values ('Four score and seven years ago...')

select PK, SomeData
from dbo.SO

delete dbo.so
where PK = @PK_to_delete

update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update

select PK, SomeData
from dbo.SO

truncate table dbo.SO
go
select COUNT(*) as CountSO from dbo.SO
go

drop table dbo.so

只有错误:

Msg 229, Level 14, State 5, Line 2
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 6
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 9
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 11
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The DELETE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The UPDATE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 21
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 1088, Level 16, State 7, Line 24
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 3701, Level 14, State 20, Line 2
Cannot drop the table 'SO', because it does not exist or you do not have permission.

尝试基本的 DML 存储过程:

declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'

declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'

exec dbo.InsertSO 'Four score and seven years ago...'

exec dbo.SelectSO 

exec dbo.DeleteSO @PK_to_delete

exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'

exec dbo.SelectSO

它们有效,因为 SP 的所有者拥有正确的权利,即使 SoUser 没有。

尝试截断或删除存储过程:

exec dbo.TruncateSO
go
exec dbo.DropSO

再次出错:

Msg 1088, Level 16, State 7, Procedure TruncateSO, Line 4
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 3701, Level 14, State 20, Procedure DropSO, Line 4
Cannot drop the table 'SO', because it does not exist or you do not have permission.

关于sql-server - 授予数据库用户有限访问执行权限的后果是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1139137/

相关文章:

sql-server - 在返回查询中不遵守更新插入的 where 子句的 Sequelize

c# - 从 SQL Server 获取列名

mysql - XAMPP: Mysql 无法启动 linux

asp.net - URL 查询字符串安全问题 (ASP.NET)

Java Applet.jar 被安全设置阻止

sql-server - 删除 MS SQL Server 中的列

sql-server - 值更改时重置行号,但分区中有重复值

android - NoSQL DB for Android 除了 MongoDB 和 CouchDB?

php - YAML 或 serialize() 在 MySQL 中存储数据

javascript - 使用 javascript 和 ruby​​ key 的对称加密