Yaa*_*lis 3 database sql-server security stored-procedures
如果我有一个仅具有有限权限的用户 - 只有 db_datareader 和 db_datawriter,这应该只允许用户查询数据和插入/编辑/删除数据,而不允许用户在数据库中添加/修改/删除表。
用户可能需要能够执行存储过程。如果向用户授予执行权限(通过以下 sql:“GRANT EXECUTE TO UserName”),之前的限制(数据读取器和数据写入器)是否仍会强制执行在用户尝试通过存储过程执行的内容上?或者执行权限真的会打开其他安全漏洞的潘多拉盒子(如果是的话,是什么)?
如果存储过程的所有者有权对表进行选择、插入、更新或删除,则只要调用者对存储过程具有执行权限,存储过程中的选择、插入、更新和删除语句就会执行,即使如果调用者无权直接对表执行选择、插入、更新或删除。
但是,除非调用者有权执行 DDL,否则存储过程无法执行 DDL,即使存储过程的所有者拥有 DDL 权限也是如此。请注意,这也适用于截断表。
答案:在您的情况下,向用户授予db_datareader和已经为用户提供了所有表上的完整 DML。db_datawriter授予执行任何存储过程不会授予任何额外的权限。
存储过程可用于通过提供所有外部程序都必须通过的门来提高数据完整性。不要授予插入、删除或更新权限,而是创建执行这些工作并强制执行有关数据的适当规则的 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)
)
Run Code Online (Sandbox Code Playgroud)
然后为基本 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
Run Code Online (Sandbox Code Playgroud)
作为 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
Run Code Online (Sandbox Code Playgroud)
或者通过存储过程执行等效操作
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
Run Code Online (Sandbox Code Playgroud)
现在,创建一个 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
Run Code Online (Sandbox Code Playgroud)
现在创建另一个用户并授予所有存储过程的执行权限。不授予任何其他权利。(假设 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
Run Code Online (Sandbox Code Playgroud)
以 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
Run Code Online (Sandbox Code Playgroud)
除了错误之外什么都没有:
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.
Run Code Online (Sandbox Code Playgroud)
尝试基本的 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
Run Code Online (Sandbox Code Playgroud)
它们之所以有效,是因为 SP 的所有者拥有正确的权利,尽管 SoUser 没有。
尝试截断或删除存储过程:
exec dbo.TruncateSO
go
exec dbo.DropSO
Run Code Online (Sandbox Code Playgroud)
再次出错:
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.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5869 次 |
| 最近记录: |