🟠 高危 | CVE-2026-65608 — Grav versions >= 1.7.0 and before 2.0.9 contain a ...
🟠 【深度分析】高危安全漏洞:CVE-2026-65608
CVSS 评分: 高危(8.7)🟠 状态: Deferred 发布时间: 2026-07-23
🔍 技术细节速览
| 字段 | 值 |
|---|---|
| CVE ID | CVE-2026-65608 |
| CVSS 评分 | 8.7 🟠 |
| 严重程度 | 高危 |
| CVSS 向量 | CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X |
| CWE 分类 | CWE-470 |
| 发布时间 | 2026-07-23 |
| 最后更新 | 2026-07-23 |
| 状态 | Deferred |
| 数据来源 | disclosure@vulncheck.com |
CVSS 4.0 评分:8.7(高危)
向量: CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
分析依据: NVD 官方数据(状态:Deferred)、CWE-470(使用不可信输入调用危险函数)
漏洞概述
CVE-2026-65608 是 Grav CMS(一个基于 PHP 的现代平面文件内容管理系统)中 FlexDirectory 组件存在的一处远程代码执行(RCE)漏洞。攻击者仅需拥有对任意基于 Flex 目录(如 Flex Users、Flex Pages、Flex Objects 或自定义 Flex 类型)的创建或更新权限,即可在目标服务器上执行任意 shell 命令。该漏洞影响 Grav 版本 >= 1.7.0 且 < 2.0.9,官方已发布 2.0.9 修复版本。
漏洞根源在于 FlexDirectory::dynamicDataField() 方法在处理 data-*@: 指令时,未充分限制被调用的 PHP 函数,仅通过 is_callable() 检查目标是否可调用,导致攻击者可利用 exec、system、passthru、shell_exec 等危险函数执行任意命令。值得注意的是,该漏洞规避了先前在 2.0.7 版本中为 Blueprint::dynamicData() 添加的验证(GHSA-fj2p-qj2f-74v5),因为 FlexDirectory 为每个 Flex 目录独立注册了处理程序,绕过了全局修复。
受影响组件与版本
| 组件 | 影响版本范围 |
|---|---|
| Grav CMS (核心) | >= 1.7.0, < 2.0.9 |
| 具体受影响模块 | FlexDirectory 组件(位于 system/src/Grav/Common/Flex/) |
- 不受影响版本: Grav 2.0.9 及以上
- 注意: 任何使用 Flex 目录功能的 Grav 站点均受影响,包括内置的 Flex Users、Flex Pages、Flex Objects 以及用户自定义的 Flex 类型。
漏洞原理分析
攻击入口:FlexDirectory::dynamicDataField()
Grav 的 Flex 组件提供了一种动态字段解析机制,允许通过 Blueprint 定义中的 data-*@: 指令(例如 data-field@: someMethod)在运行时调用回调函数来处理字段数据。该功能由 FlexDirectory::dynamicDataField() 方法实现,其内部逻辑如下:
- 解析指令: 从 Blueprint 配置中提取
data-*@:指令指定的回调名称(字符串)。 - 验证可调用性: 使用
is_callable()检查该名称是否对应一个可调用的 PHP 函数或方法。 - 执行回调: 若检查通过,则调用
call_user_func_array()执行该回调,并将攻击者可控的输入作为参数传入。
关键缺陷在于:验证仅确认目标“可被调用”,但未限制调用的具体函数。PHP 的 is_callable() 对内置函数(如 exec、system、passthru、shell_exec)同样返回 true,因此攻击者可以直接指定这些危险的 shell 执行函数作为回调,从而实现任意命令执行。
绕过修复机制(与 CVE-2026-65608 的前身关联)
在 Grav 2.0.7 版本中,开发者针对 Blueprint::dynamicData() 方法添加了安全加固(GHSA-fj2p-qj2f-74v5),禁止调用危险函数。然而,该修复仅应用于 Blueprint 类中的通用动态数据处理逻辑,并未覆盖 FlexDirectory 自定义的处理路径。由于 FlexDirectory 为每个 Flex 目录注册了独立的 dynamicDataField() 处理程序,攻击者可以通过操控 Flex 目录的 Blueprint 配置(例如修改自定义 Flex 对象的字段定义)来直接触发 FlexDirectory::dynamicDataField(),从而绕过 Blueprint::dynamicData() 的验证。
攻击前提
- 身份验证: 攻击者必须拥有一个有效的 Grav 后台账户(低权限用户即可)。
- 所需权限: 对任意基于 Flex 的目录(如用户管理、页面管理、对象管理等)的 创建(create) 或 更新(update) 权限。典型场景是普通作者或编辑角色通常拥有修改页面内容的权限,这已足够触发漏洞。
- 攻击向量: 通过网络发送构造的请求,例如在编辑页面时修改 Blueprint 中的字段定义或直接通过 API 提交恶意数据。
CVSS 4.0 向量中的关键指标:
- AV:N(网络攻击向量): 无需物理接触,远程可攻击。
- AC:L(攻击复杂度低): 无需特殊技巧即可利用。
- PR:L(低权限要求): 仅需普通用户权限。
- UI:N(无需用户交互): 攻击者自主完成。
- VC:H/VI:H/VA:H(机密性、完整性、可用性均高损失): 可完全控制服务器。
影响评估
实际威胁等级:极高
利用难度:低
攻击者只需拥有最低权限(如内容编辑者),且无需提升权限即可触发。Grav 的 Flex 功能默认启用,广泛存在于后台页面编辑、用户管理等场景。影响范围:大
- Grav 是流行 CMS,尤其被静态网站、个人博客、企业内部文档系统使用。版本 1.7.0 至 2.0.9 之间的所有安装均受影响。
- 若站点启用了自定义 Flex 类型(如电商产品、课程等),攻击面会进一步扩大。
潜在后果:严重
- 完全控制服务器:攻击者可执行任意 shell 命令,进而读取、修改任意文件,创建后门,窃取数据库凭据或 SSL 密钥。
- 数据泄露:Grav 以文件形式存储页面(如 Markdown),攻击者可读取所有用户数据、配置、插件源代码等。
- 横向移动:若服务器位于内网,可成为渗透内网其他系统的跳板。
当前状态:暂未修复(Deferred)
NVD 标记漏洞状态为“Deferred”,可能表示官方尚未发布最终补丁或存在分歧。但 Grav 2.0.9 已明确修复,建议立即升级。
关联风险
该漏洞与之前修复的 GHSA-fj2p-qj2f-74v5 类似但更隐蔽,表明安全修复可能存在“覆盖不全”或“不同路径未同步”的问题。攻击者可能通过分析源码差异找到绕过点。
修复建议
官方补丁版本
升级至 Grav 2.0.9 或更高版本
官方在 2.0.9 中为FlexDirectory::dynamicDataField()添加了与Blueprint::dynamicData()类似的白名单限制,禁止调用危险函数。立即执行更新:cd /path/to/grav bin/gpm update或手动替换
system/目录文件。
临时缓解措施(升级前)
限制用户权限:
严格审查所有用户角色,确保仅有必要的用户拥有对 Flex 目录的“创建/更新”权限。对于普通作者,移除其对 Flex User、Flex Object 等目录的编辑权限,仅保留页面编辑权限(但页面编辑仍可能通过 Flex Pages 触发,需谨慎)。禁用 Flex 目录(如可行):
在user/config/system.yaml中禁用不必要的 Flex 功能:flex: enabled: false但请注意,这将影响所有基于 Flex 的功能(如 Flex Users、Flex Pages),需根据业务需求权衡。
Web 应用防火墙规则:
在 WAF 中添加规则,拦截包含exec(、system(、passthru(、shell_exec(等字符串的 POST 请求,尤其是针对/admin路径下的 Blueprint 提交。启用日志监控:
监控/var/log/grav/grav.log中异常的函数调用记录,重点关注call_user_func_array相关日志。
长期最佳实践
- 定期更新 Grav 到最新版本,并关注官方安全公告(https://getgrav.org/blog)。
- 对自定义 Blueprint 和 Flex 类型严格审查,避免暴露
data-*@:指令给不可信用户。 - 使用 PHP 安全函数如
preg_match或白名单对is_callable的候选列表进行二次过滤。
参考资料
| 来源 | 链接 |
|---|---|
| CVE 详情页 (NVD) | https://nvd.nist.gov/vuln/detail/CVE-2026-65608 |
| CWE-470 描述(使用不可信输入调用危险函数) | https://cwe.mitre.org/data/definitions/470.html |
| Grav 官方公告(GHSA-fj2p-qj2f-74v5,先前修复) | https://github.com/getgrav/grav/security/advisories/GHSA-fj2p-qj2f-74v5 |
| Grav 2.0.9 更新日志 | https://github.com/getgrav/grav/releases/tag/2.0.9 |
PHP is_callable 文档 |
https://www.php.net/manual/en/function.is-callable.php |
总结: CVE-2026-65608 是一个高危的远程代码执行漏洞,利用了 Grav FlexDirectory 处理动态字段指令时的函数调用白名单缺失。攻击者只需低权限即可完全控制服务器。强烈建议所有 Grav 用户立即升级至 2.0.9 版本,并配合临时缓解措施降低风险。安全团队应将该漏洞纳入优先处理列表,并评估内部系统是否受到影响。