Ash授权绕过漏洞分析:当bypass策略条件评估为真时的安全缺陷

26 阅读3分钟

CVE-2025-48044:Ash授权绕过漏洞技术分析

漏洞概述

CVE-2025-48044是一个存在于ash-project/ash框架中的授权绕过漏洞,被评定为高危级别(CVSS 4.0评分8.6)。该漏洞允许攻击者在特定条件下绕过正常的授权检查,访问本应受保护的资源。

受影响版本

  • 受影响版本:从3.6.3到3.7.0(包含两端)
  • 已修复版本:3.7.1

技术细节

漏洞位置

漏洞存在于lib/ash/policy/policy.ex文件的第69行代码中:

{%{bypass?: true}, cond_expr, complete_expr}, {one_condition_matches, all_policies_match} ->
  {
    b(cond_expr or one_condition_matches),  # <- 漏洞:仅使用条件表达式
    b(complete_expr or all_policies_match)
  }

漏洞机制

当bypass策略的条件评估为true但其授权检查失败,且没有其他适用的策略时,系统会错误地授权请求。漏洞的核心逻辑问题在于:

  1. 最终授权决策逻辑one_condition_matches AND all_policies_match
  2. 当bypass条件为true但bypass策略失败,且后续策略具有不匹配的条件时:
    • one_condition_matches = cond_expr (bypass条件) = true(错误 - 应检查bypass是否实际授权)
    • all_policies_match = 每个策略的(complete_expr OR NOT cond_expr)
    • 对于不匹配的策略:(false OR NOT false) = true(策略不适用)
  3. 最终结果true AND true = true(错误授权)

bypass条件单独满足"至少一个策略适用"的要求,即使bypass未能实际授权。

修复方案

第69行的修复方法是用complete_expr替换cond_expr

{%{bypass?: true}, _cond_expr, complete_expr}, {one_condition_matches, all_policies_match} ->
  {
    b(complete_expr or one_condition_matches),  # <- 已修复
    b(complete_expr or all_policies_match)
  }

第52行也应更新以保持一致性(尽管在实践中,只有当bypass是最后一个策略时才会触发,这使得它在实践中偶然安全):

{%{bypass?: true}, _cond_expr, complete_expr}, {one_condition_matches, true} ->
  {
    b(complete_expr or one_condition_matches),  # <- 为了保持一致性
    complete_expr
  }

漏洞影响

资源具有bypass策略时,在以下情况下可能在没有适当授权的情况下被访问:

  1. Bypass条件评估为true
  2. Bypass授权检查失败
  3. 存在其他策略但它们的条件不匹配

概念验证示例

策略配置示例

policies do
  bypass always() do
    authorize_if actor_attribute_equals(:is_admin, true)
  end

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

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

测试代码

test "bypass policy bug" do
  policies = [
    %Ash.Policy.Policy{
      bypass?: true,
      condition: [{Ash.Policy.Check.Static, result: true}],  # 条件 = true
      policies: [
        %Ash.Policy.Check{
          type: :authorize_if,
          check: {Ash.Policy.Check.Static, result: false},  # 策略 = 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(拒绝)
  # 实际(main分支上):true(错误授权)
end

安全建议

  1. 立即升级:所有使用ash版本3.6.3至3.7.0的用户应立即升级到3.7.1或更高版本
  2. 代码审查:检查项目中是否存在类似的授权逻辑漏洞
  3. 安全测试:对授权逻辑进行全面的安全测试,特别是边缘情况

相关参考

CVSS评分详情

CVSS 4.0指标

  • 基础评分:8.6(高危)
  • 攻击向量:网络(AV:N)
  • 攻击复杂度:低(AC:L)
  • 权限要求:低(PR:L)
  • 用户交互:无(UI:N)
  • 机密性影响:高(VC:H)
  • 完整性影响:高(VI:H)
  • 可用性影响:无(VA:N)

弱点枚举

  • CWE-ID:CWE-863
  • CWE名称:不正确的授权

致谢

此漏洞由以下人员报告和审查:

  • 报告者:jechol
  • 分析员:maennchen
  • 修复审查员:zachdaniel glyoVzOLZA9nMhz/bDHDAWzfRfZ0dSZtQUalpUyOmxfcc5naRhCCGp0pW3Se/U9NHFY61P/g7Wma8oDTbll52Q==