Mar*_*ith 12 sql-server permissions
想象以下场景
CREATE DATABASE test
GO
USE test;
CREATE TABLE dbo.Customer
(
CustomerId INT,
Email VARCHAR(100),
SensitiveData VARCHAR(20)
);
INSERT INTO dbo.Customer
VALUES (1,'abc@foo.com','12346789');
Run Code Online (Sandbox Code Playgroud)
在某些时候,编写了一个 ETL 过程,在test
数据库中执行一些活动。
CREATE USER etlUser WITHOUT LOGIN; /*For demo purposes*/
CREATE TABLE dbo.StagingTable
(
StagingTableId INT,
SomeData VARCHAR(100),
)
GRANT UPDATE,INSERT,DELETE,SELECT,ALTER ON dbo.StagingTable TO etlUser;
DENY SELECT ON dbo.Customer TO etlUser;
DENY SELECT ON dbo.Customer (SensitiveData) TO etlUser; /*For good measure*/
Run Code Online (Sandbox Code Playgroud)
etlUser 不应该对Customer
表(当然也不是对SensitiveData
列)具有权限,因此上面明确拒绝了这些权限。
ETL 过程会截断,dbo.StagingTable
因此被授予ALTER
表权限。
这在安全审计期间被标记。这个场景有多危险?
Mar*_*ith 17
相当危险...
除了更改StagingTable
自身结构的明显权限之外,该ALTER TABLE
权限还允许他们在表上创建触发器。因此,在这种情况下,通过所有权链接,他们能够看到敏感的客户数据(尽管有明确的DENY
权限)并在第二个表上进行破坏。
EXECUTE AS user='etlUser'
GO
CREATE OR ALTER TRIGGER TR ON dbo.StagingTable AFTER UPDATE AS
/*Exposure of sensitive data*/
SELECT * FROM dbo.Customer;
/*Vandalism*/
DELETE FROM dbo.Customer;
go
--Fire the trigger
UPDATE dbo.StagingTable SET SomeData = SomeData WHERE 1=0;
REVERT
Run Code Online (Sandbox Code Playgroud)
除了能够添加触发器之外,ALTER TABLE权限还允许:
它还允许删除列,但这不太可能被忽视(因为我们似乎在这里寻找更具欺骗性而非恶意的潜在操作)。
幸运的是,从来没有必要将此权限授予任何人,也没有必要将其包装在使用该EXECUTE AS
子句的存储过程中(通常后跟'dbo'
或OWNER
)。模块签名允许轻松抽象签名代码(存储过程、触发器、标量 UDF 和多语句 TVF)背后的特权操作。我在 DBA.SE 上的以下答案中提供了示例代码,显示了如何完成此操作:
这两个答案之间的区别在于授予基于签名的用户的权限。要授予的权限(或要添加的 DB 角色)取决于所需的范围。如果您只需要对单个表的权限,则只授予ALTER
该表的权限。如果特定 Schema 中的所有表都需要权限,则不要向单个表授予权限,而是将权限授予 Schema 本身。等等。
与专门为 ETL 用户创建模式或使用EXECUTE AS
子句相比,模块签名是一些额外的步骤,但是:
EXECUTE
允许那些获得该代码权限的人。作为架构所有者允许某些不必要的隐式权限。而且,使用EXECUTE AS 'dbo'
或EXECUTE AS OWNER
(假设所有者dbo
)会给整个过程,从这一点向前,dbo
权限,而不仅仅是存储过程/触发器/函数,您使用EXECUTE AS
与。模块签名将权限仅限于您签名的代码,而不是签名代码调用的任何代码。