Ash框架过滤器授权漏洞分析
漏洞概述
Ash框架在过滤器授权实现中存在两个边界情况,可能导致策略编译器/授权器生成过于宽松的过滤器:
-
绕过策略问题:当使用在运行时永远无法通过的绕过策略条件时,策略被编译为
OR(AND(condition, compiled_policies), NOT(condition))。如果条件在运行时永远不为真,NOT(condition)分支将评估为真值,导致整个表达式变得宽松。 -
运行时策略问题:简化为"无适用检查"(空SAT场景)的运行时策略场景被当作空子句丢弃,而不是被视为false,这同样可能产生过于宽松的过滤器。
影响范围
这些漏洞可能允许读取操作返回本应被策略排除的记录。
技术细节
受影响条件
依赖基于过滤器的授权并定义以下内容的项目可能受到影响:
- 包含
bypass ... do ... end块,其条件仅在运行时可解析,且在特定请求上下文中永远无法通过 - 定义运行时检查,这些检查简化为子句的空场景
主要受影响的操作:受过滤器策略保护的读取操作。非过滤器策略(如硬性禁止)不受影响。
修复方案
此补丁修正了两个行为:
-
Ash.Policy.Policy.compile_policy_expression/1现在将绕过块视为AND(condition_expression, compiled_policies),而不是OR(AND(...), NOT(condition_expression))。这移除了当绕过条件永远无法通过时的宽松NOT(condition)逃生舱口。 -
Ash.Policy.Authorizer现在将空SAT场景(scenario == %{})视为false,确保不可能的场景不会坍塌为无操作并无意中扩大过滤器。
相关更改位于:
lib/ash/policy/policy.ex(绕过编译)lib/ash/policy/authorizer/authorizer.ex(场景处理/auto_filter规范化)
解决方案
临时解决方案
- 避免使用条件仅在运行时可决定且在某些上下文中可能永远为假的绕过策略
- 为敏感读取添加明确的最终
forbid_if always()保护作为额外保障 - 在可行的情况下,将运行时未知检查替换为严格/编译时检查,或重构以避免空SAT场景
升级建议
升级到Ash框架3.6.2或更高版本。
参考信息
- CVE ID: CVE-2025-48043
- GHSA ID: GHSA-7r7f-9xpj-jmr7
- 受影响版本: < 3.6.2
- 修复版本: 3.6.2
- 严重程度: 高(CVSS评分8.6)