[聚合文章] SQL Server 安全篇——数据层面安全性(2)——所有权链接( Ownership Chaining)

SQL Server 2018-01-25 16 阅读

接上文: SQL Server 安全篇——数据层面安全性(1)——架构

Ownership Chaining

SQL Server 2016提供了一种叫行级安全性(row-level security,RLS)的功能,但是这种功能是比较有限制的,标准的方式是使用视图或存储过程来限制数据返回。并且通过对视图或存储过程的授权,可以使得用户不需要直接访问底层实体表。 

这种方式的实现基础来自于一个叫“所有权链接(Ownership Chaining)”。当多个对象被一个查询顺序调用时,SQL Server会把这个视为一个链。当你把对象“链”在一起时,权限检查则会变得很复杂,特别是要依据对象的“架构”。

比如有一个视图V1,访问两个表:t1和t2。如果三个对象都属于同一个拥有者,那么在SELECT视图时,视图会对调用者进行权限校验,但是在表上的权限则不会进行校验。意味着如果想授权另一个用户UserB对表T1的特定行有访问权限,可以创建一个视图并查询用户被允许的那些行。此时,用户可以借助视图来返回数据而不用直接访问表。

但是所有者链接也会在某些时候发生中断,按前面的说法,就是在不同的拥有者情况下。SQL Server需要对这些不同的拥有者进行权限校验,如果用户没有权限访问某些底层表时会报错。在大部分情况下ownership chaining是一个好东西,因为它可以让你建立一个保护访问资源的机制。但是某些时候也会破坏安全性,因为Ownership chains会导致DENY设置被绕过,原因是权限校验不会对GRANT或DENY进行。

Cross DB Ownership Chaining

到Ownership Chaining,那就要顺带提一下Cross db Ownership Chaining,前面提到的是库内的Ownership Chaining,Cross DB Ownership Chaining则是在实例层面跨库的所有权链接。如果cross db Ownership Chaining=0则禁用跨库所有权链接,1则为启用。可以通过SELECT is_db_chaining_on, name FROM sys.databases;来查询是否启用。

由于安全原因,微软并不建议启用这个只有sysadmin角色成员才能控制的功能,除非所有库都必须参加。

假设一个服务器上有不同项目的库,彼此之间不应该互访,此时有一个库A的存储过程P1想访问库B的数据。如果开放了Cross db Ownership Chaining,那么B会放行P1访问,这就会导致不必要的安全风险。

小结

Ownership Chaining 通过对某个对象(如视图)的权限配置来允许管理多个对象(如表)的访问,在某些情况下对性能也有少许提升(因为权限检查必然需要消耗时间和资源)。它对管理对数据库的权限时非常有用,但是如果SQL Server认为某个用户授予了对访问链中第一个对象(视图)的权限,就会认为这个用户也有共享该视图所引用的所有视图和表的权限。在正式环境下是这种“认为”是不成立和不合理的。因此,首先不要在某些对象中引用过多对象和嵌套引用,这会加大安全风险跟问题侦测工作量。其次,可以考虑借用2016引入的RLS功能。

另外,特权用户可以使用跨数据库所有权链接来访问自身数据库之外的数据库对象,只需要在需要访问的库B中创建一个本库A已存在的db_onwer成员的用户,然后在A中创建一个调用B中用户可访问的对象,即可绕过权限来访问不应该访问的资源。这就会带来不安全性。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。