安全研究 >> 安全研究详情

运维日记|SQL server 所有权链(上篇)

作者: 美创科技安全实验室发布日期: 09月01日

XXX,你好,我们的工作人员在删除数据时意外将整表删除了,现已恢复数据,想咨询下有什么办法防止这种误删操作吗?


在了解了客户需求后,发现该工作人员必须每天删除固定时间段内的数据,所以,简单一刀切(回收delete的权限)的方法明显不可用……


是不是真的束手无策了???哈哈哈,那我今天就给大家带来一个SQL server鲜为人知的知识点:SQL server 所有权链


一、什么是SQL server所有权链


       当一个对象引用另外一个对象且两个对象有相同的所有者时,就形成了所有权链。当所有权链形成时,SQL Server 将仅仅检查第一个对象的权限,即便第二个对象拒绝了用户的权限。


二、理解SQL server对象的有效所有者


       上面提到,一个对象引用另一个对象,很好理解,可是拥有相同的所有者,该如何理解呢?


       在SQL server 2005以后,我们创建数据库对象,比如表、存储过程的时候不会特意的去指定其所有者,但并不代表没有,细致的朋友肯定发现,默认情况下我们的表、存储过程的所有者是dbo,但这不代表只要创建对象,其所有者就是dbo。


    是不是听起来有点绕口,因为我们平时很少会去关注所有者这一概念,下面我们演示一下,方便大家理解。



2.1 创建3个架构


       为什么要创建架构呢,因为,架构必须存在所有者,如果创建的时候不指定,那么创建的用户就会成为该架构的所有者。


--1、创建架构schema_1、schema_2和schema_3(其中schema_3指定所有者为db_datareader)



--2、查询架构及其所有者



2.2 创建三个对象


--1、创建表TestTable、存储过程QueryTestTable和表TestTable_1



--2 、查询三个对象的所有者



呦呵,TestTable_1表的所有者不是dbo,那么这个时候我们就明白了,所谓对象的所有者,在不指定的时候其实就是该对象所属架构的所有者。


三、所有权链使用演示


3.1 创建用户user_1



3.2 往schema_1.TestTable里插入数据



3.3 使用user_1登录查询该表



3.4 使用user_1执行存储过程



妈耶,什么鬼,同样是user_1,为啥直接查询被拒绝,通过存储过程就可行呢,真神奇……


四、总结


通过上面的演示,我们可以看到,dsz.schema_1.TestTable表和

[schema_2].[QueryTestTable]存储过程拥有相同的所有者dbo,所以在用存储过程调用表的时候,只验证用户是否有执行该存储过程的权限,不会去对调用的表做第二次权限校验,这就是SQL server所有权链。


所以,针对前文客户所提的需求,我们只需要用存储过程调用表,通过传递日期参数进行删除,不提供对表直接进行delete,这样就完美避免了误删全表的可能,很有魅力吧。


如果大家对所有权链很有兴趣,可持续关注公众号,后续我会分享不同数据库间如何实现所有权链以及如何合理使用。

服务热线:400-811-3777
Copyright ©2005-2020 杭州美创科技有限公司. All Rights Reserved. 浙ICP备12021012号-1 网站地图