漏洞概述
- 标识符: CVE-2025-48043 (GHSA-7r7f-9xpj-jmr7)
- 严重性: 高危 (CVSS 4.0 评分: 8.6)
- 影响组件: Ash Framework (
ashErlang包) - 受影响版本: < 3.6.2
- 已修复版本: 3.6.2
漏洞描述
当使用基于过滤器的授权机制时,两个边界情况可能导致策略编译器/授权器生成过于宽松(允许通过)的过滤器:
-
运行时不可能满足的绕过策略: 对于在运行时条件永远无法满足的
bypass策略,其编译逻辑存在问题。原本应为OR(AND(条件, 编译后的策略), NOT(条件))的结构,在条件永远为假时,NOT(条件)分支被评估为真,导致整个表达式变得宽松。 -
运行时策略场景简化为空: 当运行时检查策略简化到“没有适用的检查”(即空的SAT场景)时,系统错误地将其视为空子句并丢弃,而不是视为
false,这同样可能产生过于宽泛的过滤器。
这些缺陷可能导致读取操作返回本应被策略排除的记录。
影响范围
依赖过滤器授权并定义以下内容之一的项目可能受到影响:
- 定义了
bypass ... do ... end代码块,其条件仅在运行时解析,并且在特定请求上下文中永远无法通过。 - 定义了运行时检查,且该检查会简化为某个子句的空场景。
主要受影响的动作: 受过滤器策略保护的读取操作。非过滤器策略(例如硬性禁止策略)不受影响。
技术细节
本次修复纠正了两种行为:
-
Ash.Policy.Policy.compile_policy_expression/1: 现在将绕过块视为AND(条件表达式, 编译后的策略),而不是原来的OR(AND(...), NOT(条件表达式))。这移除了当绕过条件永远无法满足时,NOT(条件)这个宽松的“逃生通道”。 -
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) 用于验证修复后的行为。
缓解措施
- 升级: 将Ash框架升级到版本 3.6.2 或更高。
- 代码审查:
- 避免使用那些条件仅在运行时决定、且在某些上下文中可能永远为假的
bypass策略;对于此类情况,建议使用没有bypass的显式authorize_if/forbid_if块。 - 对于敏感的读取操作,可以添加一个显式的最终
forbid_if always()守卫作为备用安全措施,直到能够升级。 - 在可行的情况下,将运行时未知的检查替换为严格的编译时检查,或重构代码以避免出现空的SAT场景。
- 避免使用那些条件仅在运行时决定、且在某些上下文中可能永远为假的
判断是否受影响
如果您的项目同时满足以下所有条件,则很可能受到影响:
- 使用了过滤器授权;并且
- 定义了访问类型为
:runtime且其后没有任何策略的bypass块;或者 - 定义了条件在运行时评估(例如,
strict_check/3返回:unknown且check/4在某些上下文中可能永远不会成功)且其后没有任何策略的bypass块。
一个快速的验证方法是:在存在上述绕过或运行时为假条件的情况下,发出一个预期返回零条记录的读取查询,并验证它确实返回空列表 []。修复后新增的测试 bypass works with filter policies 演示了修正后的、非宽松行为。
参考链接
- 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 (发布版本)
额外信息
- CWE分类: CWE-863 - 不正确的授权
- EPSS评分: 0.106% (未来30天内被利用的概率,处于第29百分位)
- 报告者: maennchen
- 修复审阅者: zachdaniel