SA-CORE-2019-008 Drupal访问绕过漏洞分析
字数 2041 2025-08-27 12:33:42

Drupal访问绕过漏洞(SA-CORE-2019-008/CVE-2019-6342)深度分析与教学文档

漏洞概述

漏洞编号: CVE-2019-6342
Drupal安全公告: SA-CORE-2019-008
发布日期: 2019年7月17日
影响版本: Drupal 8.7.4
漏洞类型: 访问控制绕过
漏洞危害: 攻击者可在未授权情况下执行文章发布、修改、删除等操作

受影响环境

  • 仅影响Drupal 8.7.4版本
  • 需要启用Workspaces模块(实验性模块,默认不启用)

漏洞复现步骤

  1. 环境准备:

    • 安装Drupal 8.7.4
    • 以管理员身份登录后台
  2. 启用漏洞模块:

    • 访问/admin/modules
    • 勾选并安装"Workspaces"模块
    • 确认安装成功(页面顶部出现Workspaces模式切换界面)
  3. 漏洞验证:

    • 使用另一个浏览器(未登录任何账户)访问
    • 直接访问http://[site-url]/node/add/article
    • 验证是否可以无需权限添加文章
    • 受影响操作包括: 添加、修改、删除文章及上传附件等

漏洞技术分析

Workspaces模块功能背景

  • 引入版本: Drupal 8.6核心新增的实验模块
  • 主要功能: 方便管理员批量发布/修改多个内容
  • 两种工作模式:
    • Stage模式: 修改内容不会立即更新,需通过"Deploy to Live"发布
    • Live模式: 修改立即生效(默认模式)

漏洞产生原因

权限检查流程中的设计缺陷,具体位于EntityAccess权限鉴定模块。

详细调用流程

  1. 请求处理流程:

    • 请求由RouterListener类的onKernelRequest()方法处理
    • 调用AccessAwareRouter->matchRequest()
    • 调用AccessManager->checkRequest()
    • 最终通过call_user_func_array回调具体权限检查方法
  2. 权限检查流程(以发布文章为例):

    • 回调access_check.node.add
    • NodeAccessControlHandler处理(继承自EntityAccessControlHandler)
    • createAccess()方法中回调create_access权限
    • 拼接模块名和钩子作为回调函数($function = module_hook)
    • 最终调用workspaces_entity_create_access()

关键漏洞点分析

问题函数: bypassAccessResult()

  1. 设计意图:

    • 检查用户是否有"绕过节点访问权限"(bypass node access)
    • Workspaces特有功能: "如果用户在各自的激活工作区中,则拥有所有权限"
    • 正常情况下需在admin/people/permissions中配置"Bypass content entity access in own workspace"权限
  2. 漏洞代码:

    $owner_has_access->orIf(access_bypass);
    
    • 补丁将此行改为andIf
    • orIfandIf的区别:
      • orIf: 对"中立"结果,是否允许由调用者决定
      • andIf: 对"中立"结果视为禁止
    • 错误使用orIf导致默认情况下返回AccessResultAllowed(允许)而非AccessResultNeutral(禁止)
  3. 权限检查结果:

    • 漏洞版本: 返回AccessResultAllowed对象
    • 修复版本: 返回AccessResultNeutral对象
    • AccessAwareRouter->checkAccess()会根据isAllowed()结果决定是否抛出异常

完整调用栈

Drupal\workspaces\EntityAccess->bypassAccessResult()
Drupal\workspaces\EntityAccess->entityCreateAccess()
...
Drupal\Core\Extension\ModuleHandler->invokeAll()
Drupal\node\NodeAccessControlHandler->createAccess()
Drupal\node\Access\NodeAddAccessCheck->access()
Drupal\Core\Access\AccessManager->performCheck()
Drupal\Core\Routing\AccessAwareRouter->checkAccess()
Drupal\Core\Routing\AccessAwareRouter->matchRequest()
Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest()
...
DrupalKernel.php:693, Drupal\Core\DrupalKernel->handle()
index.php:19, {main}()

修复方案

  1. 官方补丁:

    • 升级到Drupal 8.7.4以上版本
    • 补丁修改了bypassAccessResult()方法中的逻辑判断方式
  2. 临时解决方案:

    • 禁用Workspaces模块(实验性模块,非必需功能)

漏洞影响评估

  • 影响范围有限:
    • 仅影响特定版本(8.7.4)
    • 需要启用非默认模块(Workspaces)
  • 攻击前提:
    • 攻击者需要知道网站启用了Workspaces模块
    • 无法直接利用于未启用该模块的站点

教学总结

  1. 权限检查机制:

    • 理解Drupal的权限检查流程和回调机制
    • 掌握EntityAccessControlHandler的工作方式
  2. 安全编码要点:

    • 权限检查中"中立"状态的处理需谨慎
    • orIfandIf的逻辑差异可能导致严重安全问题
    • 实验性模块的安全审计同样重要
  3. 漏洞分析技巧:

    • 关注权限检查流程中的逻辑判断
    • 理解框架核心安全机制的设计意图
    • 掌握调用栈分析方法

扩展思考

  1. 为什么实验性模块的安全问题也需要重视?
  2. 在权限设计中,如何处理"默认拒绝"与"默认允许"的平衡?
  3. 如何设计更安全的权限检查回调机制?
Drupal访问绕过漏洞(SA-CORE-2019-008/CVE-2019-6342)深度分析与教学文档 漏洞概述 漏洞编号 : CVE-2019-6342 Drupal安全公告 : SA-CORE-2019-008 发布日期 : 2019年7月17日 影响版本 : Drupal 8.7.4 漏洞类型 : 访问控制绕过 漏洞危害 : 攻击者可在未授权情况下执行文章发布、修改、删除等操作 受影响环境 仅影响Drupal 8.7.4版本 需要启用Workspaces模块(实验性模块,默认不启用) 漏洞复现步骤 环境准备 : 安装Drupal 8.7.4 以管理员身份登录后台 启用漏洞模块 : 访问 /admin/modules 勾选并安装"Workspaces"模块 确认安装成功(页面顶部出现Workspaces模式切换界面) 漏洞验证 : 使用另一个浏览器(未登录任何账户)访问 直接访问 http://[site-url]/node/add/article 验证是否可以无需权限添加文章 受影响操作包括: 添加、修改、删除文章及上传附件等 漏洞技术分析 Workspaces模块功能背景 引入版本: Drupal 8.6核心新增的实验模块 主要功能: 方便管理员批量发布/修改多个内容 两种工作模式: Stage模式 : 修改内容不会立即更新,需通过"Deploy to Live"发布 Live模式 : 修改立即生效(默认模式) 漏洞产生原因 权限检查流程中的设计缺陷,具体位于 EntityAccess 权限鉴定模块。 详细调用流程 请求处理流程 : 请求由 RouterListener 类的 onKernelRequest() 方法处理 调用 AccessAwareRouter->matchRequest() 调用 AccessManager->checkRequest() 最终通过 call_user_func_array 回调具体权限检查方法 权限检查流程 (以发布文章为例): 回调 access_check.node.add 由 NodeAccessControlHandler 处理(继承自 EntityAccessControlHandler ) 在 createAccess() 方法中回调 create_access 权限 拼接模块名和钩子作为回调函数( $function = module_hook ) 最终调用 workspaces_entity_create_access() 关键漏洞点分析 问题函数 : bypassAccessResult() 设计意图 : 检查用户是否有"绕过节点访问权限"(bypass node access) Workspaces特有功能: "如果用户在各自的激活工作区中,则拥有所有权限" 正常情况下需在 admin/people/permissions 中配置"Bypass content entity access in own workspace"权限 漏洞代码 : 补丁将此行改为 andIf orIf 和 andIf 的区别: orIf : 对"中立"结果,是否允许由调用者决定 andIf : 对"中立"结果视为禁止 错误使用 orIf 导致默认情况下返回 AccessResultAllowed (允许)而非 AccessResultNeutral (禁止) 权限检查结果 : 漏洞版本: 返回 AccessResultAllowed 对象 修复版本: 返回 AccessResultNeutral 对象 AccessAwareRouter->checkAccess() 会根据 isAllowed() 结果决定是否抛出异常 完整调用栈 修复方案 官方补丁 : 升级到Drupal 8.7.4以上版本 补丁修改了 bypassAccessResult() 方法中的逻辑判断方式 临时解决方案 : 禁用Workspaces模块(实验性模块,非必需功能) 漏洞影响评估 影响范围有限 : 仅影响特定版本(8.7.4) 需要启用非默认模块(Workspaces) 攻击前提 : 攻击者需要知道网站启用了Workspaces模块 无法直接利用于未启用该模块的站点 教学总结 权限检查机制 : 理解Drupal的权限检查流程和回调机制 掌握 EntityAccessControlHandler 的工作方式 安全编码要点 : 权限检查中"中立"状态的处理需谨慎 orIf 和 andIf 的逻辑差异可能导致严重安全问题 实验性模块的安全审计同样重要 漏洞分析技巧 : 关注权限检查流程中的逻辑判断 理解框架核心安全机制的设计意图 掌握调用栈分析方法 扩展思考 为什么实验性模块的安全问题也需要重视? 在权限设计中,如何处理"默认拒绝"与"默认允许"的平衡? 如何设计更安全的权限检查回调机制?