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模块(实验性模块,默认不启用)
漏洞复现步骤
-
环境准备:
- 安装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"权限
-
漏洞代码:
$owner_has_access->orIf(access_bypass);- 补丁将此行改为
andIf orIf和andIf的区别:orIf: 对"中立"结果,是否允许由调用者决定andIf: 对"中立"结果视为禁止
- 错误使用
orIf导致默认情况下返回AccessResultAllowed(允许)而非AccessResultNeutral(禁止)
- 补丁将此行改为
-
权限检查结果:
- 漏洞版本: 返回
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}()
修复方案
-
官方补丁:
- 升级到Drupal 8.7.4以上版本
- 补丁修改了
bypassAccessResult()方法中的逻辑判断方式
-
临时解决方案:
- 禁用Workspaces模块(实验性模块,非必需功能)
漏洞影响评估
- 影响范围有限:
- 仅影响特定版本(8.7.4)
- 需要启用非默认模块(Workspaces)
- 攻击前提:
- 攻击者需要知道网站启用了Workspaces模块
- 无法直接利用于未启用该模块的站点
教学总结
-
权限检查机制:
- 理解Drupal的权限检查流程和回调机制
- 掌握
EntityAccessControlHandler的工作方式
-
安全编码要点:
- 权限检查中"中立"状态的处理需谨慎
orIf和andIf的逻辑差异可能导致严重安全问题- 实验性模块的安全审计同样重要
-
漏洞分析技巧:
- 关注权限检查流程中的逻辑判断
- 理解框架核心安全机制的设计意图
- 掌握调用栈分析方法
扩展思考
- 为什么实验性模块的安全问题也需要重视?
- 在权限设计中,如何处理"默认拒绝"与"默认允许"的平衡?
- 如何设计更安全的权限检查回调机制?