行级安全更新块谓词不起作用
Row Level Security update block predicate not working
考虑以下 tables:
客户端 table 列:
- client_guid(uniqueidentifier - 主键)
- client_description
带有列的工单 table:
- ticket_guid(uniqueidentifier - 主键)
- ticket_client_guid(uniqueidentifier - 客户端外键table)
- ticket_description.
考虑使用以下更新谓词函数,它应该允许客户只更新他们自己的票:
CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_guid AS sysname) RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) =
(SELECT ticket_client_guid
FROM dbo.ticket
WHERE ticket_guid = @ticket_guid)
然后我们有应用谓词 fn 的安全策略:
CREATE SECURITY POLICY [Security].[ticket_security]
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_guid]) ON [dbo].[ticket] BEFORE UPDATE
WITH (STATE = ON, SCHEMABINDING = ON)
问题:客户能够将属于其他人的工单重新分配(更改工单_client_guid)给他。
注意:如果更新了其他一些票证字段,安全性工作得很好并且符合预期。
问题:这种行为是预期的吗?是否有解决此问题的方法?
注意:我尝试使用更新语句之前和之后的语句,并且在尝试更新谓词 fn (ticket_client_guid) 中引用的列时,其中 none 按预期运行。
块谓词在执行相应的 DML 操作后计算。因此,READ UNCOMMITTED 查询可以看到将回滚的临时值。
如果有人将 ticket_client_guid 更新为他们的 ID,如果您在 table 中查询它,谓词将使用该新值进行安全检查。
我认为您需要使用传入函数的值,因此您可能必须使用其他 guid,以便它可以与原始值一起传递。也许
CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_client_guid AS uniqueidentifier)
RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) = @ticket_client_guid
CREATE SECURITY POLICY [Security].[ticket_security]
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_client_guid]) ON [dbo].[ticket] BEFORE UPDATE
WITH (STATE = ON, SCHEMABINDING = ON)
考虑以下 tables:
客户端 table 列:
- client_guid(uniqueidentifier - 主键)
- client_description
带有列的工单 table:
- ticket_guid(uniqueidentifier - 主键)
- ticket_client_guid(uniqueidentifier - 客户端外键table)
- ticket_description.
考虑使用以下更新谓词函数,它应该允许客户只更新他们自己的票:
CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_guid AS sysname) RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) =
(SELECT ticket_client_guid
FROM dbo.ticket
WHERE ticket_guid = @ticket_guid)
然后我们有应用谓词 fn 的安全策略:
CREATE SECURITY POLICY [Security].[ticket_security]
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_guid]) ON [dbo].[ticket] BEFORE UPDATE
WITH (STATE = ON, SCHEMABINDING = ON)
问题:客户能够将属于其他人的工单重新分配(更改工单_client_guid)给他。 注意:如果更新了其他一些票证字段,安全性工作得很好并且符合预期。
问题:这种行为是预期的吗?是否有解决此问题的方法?
注意:我尝试使用更新语句之前和之后的语句,并且在尝试更新谓词 fn (ticket_client_guid) 中引用的列时,其中 none 按预期运行。
块谓词在执行相应的 DML 操作后计算。因此,READ UNCOMMITTED 查询可以看到将回滚的临时值。
如果有人将 ticket_client_guid 更新为他们的 ID,如果您在 table 中查询它,谓词将使用该新值进行安全检查。
我认为您需要使用传入函数的值,因此您可能必须使用其他 guid,以便它可以与原始值一起传递。也许
CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_client_guid AS uniqueidentifier)
RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) = @ticket_client_guid
CREATE SECURITY POLICY [Security].[ticket_security]
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_client_guid]) ON [dbo].[ticket] BEFORE UPDATE
WITH (STATE = ON, SCHEMABINDING = ON)