如何限制数据库用户limited_u通过视图、存储过程间接访问表
解决limited_u通过视图/存储过程间接访问底层表的问题
核心原因
问题出在SQL Server的所有权链机制:当视图/存储过程与底层表的所有者相同时,SQL会跳过对底层表的权限检查,导致即使limited_u没有t3/t4的直接权限,也能通过这些模块间接操作。
具体解决方案
1. 打破视图的所有权链
如果get_t3视图和t3表的所有者一致,修改视图的所有者为一个与t3不同的用户(比如非dbo的独立用户),强制SQL检查用户对t3的权限:
ALTER AUTHORIZATION ON VIEW::get_t3 TO [custom_owner];
注意:不要批量修改所有权,只针对该视图单独设置,避免影响其他用户的权限。
2. 对用户设置显式DENY权限
DENY是SQL中优先级最高的权限,会覆盖所有间接权限(包括所有权链带来的访问权)。直接对limited_u设置针对t3和t4的拒绝权限:
-- 禁止limited_u读取t3(无论通过何种方式) DENY SELECT ON t3 TO limited_u; -- 禁止limited_u更新t4(无论通过何种方式) DENY UPDATE ON t4 TO limited_u;
如果limited_u属于某个拥有t3/t4权限的数据库角色,需要确保角色层面没有冲突的权限,或者使用CASCADE选项级联拒绝:
DENY SELECT ON t3 TO limited_u CASCADE;
3. 修改存储过程的执行上下文
如果update_t4存储过程默认以所有者权限执行(EXECUTE AS OWNER),会绕过调用者的权限检查。修改为以调用者权限执行,强制检查limited_u的t4权限:
ALTER PROCEDURE update_t4 WITH EXECUTE AS CALLER AS -- 原存储过程的业务逻辑 GO
这样执行存储过程时,SQL会使用limited_u的权限,而该用户已被DENYt4的UPDATE权限,自然无法完成操作。
验证限制是否生效
执行以下命令模拟limited_u的操作,确认权限限制生效:
EXECUTE AS USER = 'limited_u'; -- 尝试访问视图,应返回权限错误 SELECT * FROM get_t3; -- 尝试执行存储过程,应返回权限错误 EXEC update_t4; REVERT;
内容的提问来源于stack exchange,提问作者Ano Nymo
相关产品推荐
相关产品推荐

