Ash框架绕过策略漏洞深度解析:CVE-2025-48044授权绕过技术细节

本文详细分析了Ash框架(一个用Elixir编写的声明式资源框架)中一个严重的授权绕过漏洞CVE-2025-48044。该漏洞存在于策略评估逻辑中,当绕过策略的条件评估为真但其授权检查失败时,可能导致未经授权的访问。文章包含漏洞原理、受影响版本、修复方法及概念验证代码。

漏洞概述

CVE-2025-48044 是Ash框架中的一个高严重性漏洞(CVSS评分为8.6),涉及授权绕过问题。Ash是一个用Elixir编写的声明式资源框架,用于构建可扩展的应用程序。

受影响版本

  • 受影响的版本>= 3.6.3, <= 3.7.0
  • 已修复版本3.7.1

漏洞详情

当满足以下条件时,存在绕过策略的资源可能会在未经适当授权的情况下被访问:

  1. 绕过条件评估为真
  2. 绕过授权检查失败
  3. 存在其他策略但其条件不匹配

漏洞代码位置

漏洞位于文件 lib/ash/policy/policy.ex 的第69行:

1
2
3
4
5
{%{bypass?: true}, cond_expr, complete_expr}, {one_condition_matches, all_policies_match} ->
  {
    b(cond_expr or one_condition_matches),  # <- Bug: uses condition only
    b(complete_expr or all_policies_match)
  }

漏洞原理分析

最终的授权决策由两部分构成:one_condition_matches AND all_policies_match

当绕过条件为真但绕过策略失败,并且后续策略具有不匹配的条件时,会发生以下情况:

  • one_condition_matches = cond_expr(绕过条件)= true(错误点:本应检查绕过策略是否真正授权)
  • all_policies_match = 对每个策略计算 (complete_expr OR NOT cond_expr)
    • 对于不匹配的策略:(false OR NOT false) = true(策略不适用)

最终结果true AND true = true(导致被错误地授权)

这意味着,即使绕过策略未能成功授权,仅凭其条件为真就满足了“至少有一个策略适用”的要求。

修复方案

将第69行的 cond_expr 替换为 complete_expr

1
2
3
4
5
{%{bypass?: true}, _cond_expr, complete_expr}, {one_condition_matches, all_policies_match} ->
  {
    b(complete_expr or one_condition_matches),  # <- Fixed
    b(complete_expr or all_policies_match)
  }

为了保持一致性,第52行也应进行相应更新(尽管在实践中,仅当绕过策略是最后一个策略时才会触发此情况,使其偶然安全):

1
2
3
4
5
{%{bypass?: true}, _cond_expr, complete_expr}, {one_condition_matches, true} ->
  {
    b(complete_expr or one_condition_matches),  # <- For consistency
    complete_expr
  }

概念验证(PoC)

以下策略配置示例展示了该漏洞:

1
2
3
4
5
6
7
8
9
policies do
  bypass always() do
    authorize_if actor_attribute_equals(:is_admin, true)
  end

  policy action_type(:read) do
    authorize_if always()
  end
end

在此配置下,非管理员用户可以执行创建操作(本应被拒绝)。

演示该漏洞的测试代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
test "bypass policy bug" do
  policies = [
    %Ash.Policy.Policy{
      bypass?: true,
      condition: [{Ash.Policy.Check.Static, result: true}],  # condition = true
      policies: [
        %Ash.Policy.Check{
          type: :authorize_if,
          check: {Ash.Policy.Check.Static, result: false},  # policies = false
          check_module: Ash.Policy.Check.Static,
          check_opts: [result: false]
        }
      ]
    },
    %Ash.Policy.Policy{
      bypass?: false,
      condition: [{Ash.Policy.Check.Static, result: false}],
      policies: [
        %Ash.Policy.Check{
          type: :authorize_if,
          check: {Ash.Policy.Check.Static, result: true},
          check_module: Ash.Policy.Check.Static,
          check_opts: [result: true]
        }
      ]
    }
  ]

  expression = Ash.Policy.Policy.expression(policies, %{})
  
  assert expression == false
  # 期望结果: false (拒绝)
  # 主要分支的实际结果: true (错误地授权)
end

相关链接

  • GHSA ID:GHSA-pcxq-fjp3-r752
  • NVD 详情:https://nvd.nist.gov/vuln/detail/CVE-2025-48044
  • 修复提交:ash-project/ash@8b83efa

漏洞信息

  • CWE 弱点分类:CWE-863 - 不正确的授权
  • EPSS 评分:0.106%(未来30天内被利用的概率估计,处于第29百分位)
  • CVSS v4 向量:CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

致谢

  • 报告者:jechol
  • 分析师:maennchen
  • 修复审核者:zachdaniel
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计