针对 Grav 2.0.25 中修复的 Grav content-Twig/page-cache 会话接管漏洞的最小化、仅限本地的验证工具。
安全公告:
exploit.py 被刻意限制为仅针对回环目标:
127.0.0.1::1localhost它拒绝远程主机,仅跟随回环重定向,使用 Python 标准库 HTTP 客户端,应用请求超时,并且从不打印 bearer token、cookie 或响应正文。
仅可用于你拥有或明确授权测试的 Grav 实例。该脚本会在本地实验环境中创建一个公开的证明页面。如果实验环境在多次运行之间保留内容,请在测试后删除该页面。
get_cookie() 在服务端读取访问管理员的会话 cookie。页面写入账户仅需文档中记载的低权限写入路径。它不需要 api.pages.read、admin.* 或超级管理员权限。受害管理员只需访问该公开页面一次。
2.0.19 至 2.0.24:在随附的默认 content-Twig 配置下存在漏洞。2.0.0 至 2.0.18,以及 1.7.x:仅在显式启用 content Twig 时受影响。2.0.25:已修复。运行本地 Grav 实验环境,需满足:
此双文件仓库不提供 Grav、PHP、插件或账户的配置。
通过环境变量设置凭据,使其永远不会进入源代码管理:
export GRAV_BASE_URL=http://127.0.0.1:8080
export GRAV_WRITER_USERNAME=low
export GRAV_WRITER_PASSWORD='local-writer-password'
export GRAV_ADMIN_USERNAME=admin
export GRAV_ADMIN_PASSWORD='local-admin-password'
python3 exploit.py
基础 URL 必须保持为回环地址。默认路由是随机的。在比较多次运行时,可以选择固定路由:
python3 exploit.py --route /cookie-proof-24
预期的存在漏洞结果:
page_create_status=201
admin_login_status=200
victim_page_status=200
attacker_page_status=200
cached_victim_cookie_visible_to_attacker=yes
admin_cookie_value_match=yes
replayed_cookie_api_status=200
result=VULNERABLE
当复现出预期结果时,命令退出码为 0;未复现时为 1;设置或传输错误时为 2。
对 Grav 2.0.25 运行相同命令:
python3 exploit.py --expect fixed
预期的修复后行为:攻击者不可见任何会话值,且会话重放不成功。使用 --expect fixed 时,干净的修复结果退出码为 0。
升级到 Grav 2.0.25 或更高版本。对于较旧的部署,安全公告列出了以下临时控制措施:
security.twig_content.process_enabled: false 禁用 content Twig;或system.pages.never_cache_twig: true;不要将 HttpOnly、Secure 或 SameSite 视为修复措施:存在漏洞的 cookie 读取发生在 Twig 渲染期间的服务端。
由 canhieu 报告。此仓库是对已公开安全公告的可复现性辅助工具,而非远程扫描器或凭据收集工具。