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,确保不可能的场景不会坍塌为无操作并无意中扩大过滤器。在构建auto_filter片段时,归约器还一致地将nil → false标准化。
相关变更位于:
lib/ash/policy/policy.ex(绕过编译)lib/ash/policy/authorizer/authorizer.ex(场景处理/auto_filter标准化)
新增测试:test/policy/filter_condition_test.exs(RuntimeFalsyCheck,RuntimeBypassResource)验证修正后的行为。
临时解决方案
- 避免使用条件仅在运行时可决定且在某些上下文中可能永远为假的绕过策略;对于这些情况,优先使用没有绕过的显式
authorize_if/forbid_if块。 - 在敏感读取操作中添加显式的最终
forbid_if always()保护,作为额外的安全措施,直到用户能够升级。 - 在可行的情况下,用严格/编译时检查替换运行时未知检查,或重构以避免空SAT场景。
判断是否受影响
如果所有以下条件都为真,用户很可能受到影响:
- 使用过滤器授权;且
- 定义具有
access_type :runtime且其后没有任何策略的绕过块;或 - 定义其条件在运行时评估(例如,
strict_check/3返回:unknown且runtime check/4在某些上下文中可能永远不会成功)且其后没有任何策略的绕过块
一个快速的健全性测试是:在此类绕过或运行时假条件下发出预期返回空行的读取操作,并验证它确实返回[]。包含的测试绕过与过滤器策略一起工作展示了修正后的非宽松行为。
参考信息
- GHSA-7r7f-9xpj-jmr7
- https://nvd.nist.gov/vuln/detail/CVE-2025-48043
- ash-project/ash@66d8130
- https://github.com/ash-project/ash/releases/tag/v3.6.2
安全评分
严重程度:高 CVSS总体评分:8.6/10
CVSS v4基础指标:
- 攻击向量:网络
- 攻击复杂度:低
- 攻击要求:无
- 所需权限:低
- 用户交互:无
- 脆弱系统影响指标:机密性-高,完整性-高,可用性-无
弱点分类
CWE-863:不正确授权 产品在参与者尝试访问资源或执行操作时执行授权检查,但没有正确执行检查。这允许攻击者绕过预期的访问限制。