所有权链(Ownership Chain)

所有权链(Ownership Chain)是特殊的权限评估方式,常见拥有所有权的数据库对象是:数据库对象,数据库角色(Role),和架构(Schema),在创建数据库角色,或架构时,SQL Server自动创建所有权:

CREATE ROLE role_name [ AUTHORIZATION owner_name ]
CREATE SCHEMA schema_name [AUTHORIZATION owner_name]

数据库对象,例如,数据表(Table),存储过程(SP),视图(View)等,也有所有者(Owner),从系统视图 sys.objects 中查看数据库对象的所有者,字段principal_id 指定数据库对象的所有者,如果该对象的principal_id为null,并且包含在架构中,那么该对象(schema-contained object)的所有者是其数据库架构的所有者(Schema Owner)。

一,所有权链的权限评估方式

SQL Server保证只有被授予权限的安全主体(Principal)才能访问安全对象(Securable)。当多个数据库对象相互访问时,访问的对象序列称作链(chain),链中的每个节点都是一个数据库对象。当遍历链中的各个节点时,SQL Server会采用特殊的方式来评估权限,这跟分别访问单个对象时的权限评估方式不同。

当通过链访问对象时,SQL Server首先把对象的所有者与调用对象的所有者(链中的上一个链接)进行比较。 如果两个对象拥有相同的所有者,则不会检查被引用对象的权限。每当一个对象访问具有不同所有者的另一个对象时,所有者链被中断,并且SQL Server必须检查调用者的安全上下文。这意味着,当一个对象的所有者把权限授予其他用户时,该用户能够访问该所有者拥有的所有数据库对象。

所有权链是一种特殊的权限评估方式:只检查链中对象的所有者,如果所有者相同,那么有权限访问该对象。这就是说,在所有权链中,SQL Server完全信任数据库对象的所有者(Owner),不会检查用户是否具有该对象的访问权限,只比较链中相邻的两个对象的所有者是否相同,如果相同,那么就有权限访问该对象;只在所有者不同时,才会执行权限检查。这在数据库管理上非常有用,但也会带来潜在的风险。

假设存在一个存储过程,用于从一个数据表中读取数据,用户被授予对存储过程的执行权限。如果存储过程和表具有相同的所有者,那么不需要被授予对该表的任何权限(甚至被授予拒绝权限),用户都可以访问该数据表。 但是,如果存储过程和表具有不同的所有者,那么SQL Server必须在允许访问数据之前检查用户在表上的权限。

二,修改所有者

所有权实际上是一种特殊的权限验证(AUTHORIZATION),修改所有权链的语法如下:

ALTER AUTHORIZATION
ON [ <class_type>:: ] entity_name
TO { principal_name | SCHEMA OWNER }

常见的class_type是:OBJECT、ROLE、SCHEMA

<class_type> ::=
{
OBJECT | ASSEMBLY | ASYMMETRIC KEY | AVAILABILITY GROUP | CERTIFICATE
| CONTRACT | TYPE | DATABASE | ENDPOINT | FULLTEXT CATALOG
| FULLTEXT STOPLIST | MESSAGE TYPE | REMOTE SERVICE BINDING
| ROLE | ROUTE | SCHEMA | SEARCH PROPERTY LIST | SERVER ROLE
| SERVICE | SYMMETRIC KEY | XML SCHEMA COLLECTION
}

三,所有权链关系不适用的情况

所有权链不适用于动态SQL语句,要调用执行动态TSQL语句的存储过程,调用者(caller)必须被授予访问基础表的权限,这使得应用程序更容易受到SQL注入攻击。 SQL Server提供了新的安全机制,例如,模拟和认证得签名模块,不需要授予对基础表的权限。

引文1,出自《The Ownership Chain – How the Securable Owner affects Permission Enforcement in SQL Server》:

When SQL Server executes a query, it checks the permissions of the executing principal on every object that is touched on the way. Therefore, if you run a select statement against a view that in turn selects form a table, you need to have access to both the view and the underlying table.

However, before checking the permissions on the underlying securable, SQL Server checks if the accessing object (the view) and the accessed securable (the table) have the same owner. If they have the same owner, permission checking on the accessed securable is completely skipped and access is granted.

引文2,出自《【译】第七篇 SQL Server安全跨数据库所有权链接》:

所有数据库对象都有一个所有者,并且所有者控制谁在对象上有权限。对象访问其他对象,比如存储过程在SELECT语句把多张表联接起来,形成一个连续的所有权链接,只要一个所有者拥有所有对象。
这种情况下用户只要有顶层对象(比如存储过程、视图)的权限,访问其他对象并不需要对底层对象有权限,只要存在一个连续的所有权链接就行。SQL Server一旦证实用户对顶层对象有权限就会停止检查底层对象的权限。这种设计为用户提供了更多更好的控制权,因为用户只需要直接访问对象的权限。
提示:所有权链接只适用于对象的权限,如SELECT、UPDATE和EXECUTE操作。SQL Server总是检查数据定义语言语句的权限,因为这些权限应用于语句而不是对象。

参考文档:

Ownership Chains

Security Through Ownership Chains

The Ownership Chain – How the Securable Owner affects Permission Enforcement in SQL Server

Ownership chaining in SQL Server security feature or security risk

【译】第七篇 SQL Server安全跨数据库所有权链接

上一篇:SQLserver 进程被死锁问题解决


下一篇:UVA699-落叶-二叉树