这是我的场景:
- Windows 用户 Gabe 可以
db_owner
访问数据库 DB1。 - Windows 用户 Gabe 拥有
db_reader
数据库 DB2。 - 当用户执行
UPDATE DB2.dbo.Tbl1 SET X = 1
时,他们得到“更新权限被拒绝..”如预期的那样。 - 当用户执行
DB1.dbo.uspUpdateTable
包含上述相同UPDATE
语句的过程时,它会成功。
我认为这可能是由于数据库链接或值得信赖的设置,但它们未启用。
这是db_owner
特权的预期行为吗?有没有办法防止这种情况?
SQL 服务器 2017
以下是允许通过存储存储过程进行更新的情况,而调用者对另一个数据库中的表没有更新权限。
所有权链
所涉及的
DB_CHAINING
数据库在服务器级别打开了选项集或“跨数据库所有权链接”选项。在 dbo 拥有的对象的情况下,数据库还必须具有相同的所有者(即 dbo 用户映射到相同的登录名)以维持完整的所有权链。执行为
存储过程包括一个
EXECUTE AS USER
规范,并且用户(映射到同一个登录名)存在于另一个具有更新权限的数据库中。请注意,数据库必须是TRUSTWORTHY
为了让EXECUTE AS
其他数据库尊重上下文,因此这不适用于您的情况。模块签名
存储过程由证书签名,并且从该证书创建的用户存在于具有更新表的权限的其他数据库中。
我从您的评论中看到“跨数据库所有权链接”是罪魁祸首。这也意味着数据库也具有相同的所有者。我建议您为非系统管理员角色成员可以创建 dbo 拥有的对象以降低安全风险的数据库更改数据库所有者。