CVE-2026-41894 Overview
CVE-2026-41894 is a path traversal vulnerability in SiYuan, an open-source personal knowledge management system. This vulnerability exists in versions prior to 3.6.5 and stems from an incomplete fix for CVE-2026-30869. The original patch added a denylist check (IsSensitivePath) but failed to address the root cause — a redundant url.PathUnescape() call in the serveExport() function.
An authenticated attacker can exploit this vulnerability using double URL encoding (%252e%252e) to bypass security controls and traverse directories, enabling arbitrary file reads within the workspace. This includes access to highly sensitive data such as the full SQLite database (siyuan.db), kernel logs, and all user documents.
Critical Impact
Authenticated attackers can read arbitrary workspace files including the complete SQLite database, kernel logs, and all user documents through double URL encoding bypass.
Affected Products
- SiYuan versions prior to 3.6.5
- SiYuan installations with network-accessible export functionality
- Self-hosted SiYuan instances with authenticated user access
Discovery Timeline
- 2026-04-24 - CVE-2026-41894 published to NVD
- 2026-04-27 - Last updated in NVD database
Technical Details for CVE-2026-41894
Vulnerability Analysis
This path traversal vulnerability (CWE-22) represents a bypass of a previous security fix. The original CVE-2026-30869 mitigation implemented a denylist approach via the IsSensitivePath() function, which checked for known sensitive file paths. However, this fix was incomplete because it did not address the underlying issue: a redundant url.PathUnescape() call in the serveExport() function.
When the server processes export requests, the path is URL-decoded multiple times. An attacker can craft a request with double-encoded directory traversal sequences (%252e%252e which decodes to %2e%2e then to ..). The first decode happens during normal HTTP request processing, leaving %2e%2e. The redundant PathUnescape() call then decodes this to .., allowing the attacker to escape the intended export directory.
The vulnerability requires authentication, meaning an attacker must have valid credentials to exploit it. However, once authenticated, they can access any file within the SiYuan workspace, including the SQLite database containing all notes and user data.
Root Cause
The root cause is a redundant url.PathUnescape() call in the serveExport() function within kernel/server/serve.go. When combined with standard HTTP request decoding, this creates a double-decode scenario that bypasses path validation. The previous fix only added a denylist check without removing or properly handling the redundant decode operation.
Attack Vector
The attack is network-based and requires low complexity to execute. An authenticated attacker sends a crafted HTTP request to the export endpoint with double URL-encoded path traversal sequences. For example, a path like /export/%252e%252e/%252e%252e/siyuan.db would be decoded twice, ultimately resolving to ../../siyuan.db, allowing access to the database file outside the intended export directory.
The security patch in kernel/server/serve.go adds a proper path validation check:
}
fullPath := filepath.Join(exportBaseDir, decodedPath)
+ if !gulu.File.IsSubPath(exportBaseDir, fullPath) {
+ c.Status(http.StatusUnauthorized)
+ return
+ }
+
if util.IsSensitivePath(fullPath) {
logging.LogErrorf("refuse to export sensitive file [%s]", c.Request.URL.Path)
c.Status(http.StatusForbidden)
Source: GitHub Commit Details
Additionally, the patch in kernel/util/path.go extends the sensitive file detection:
return true
}
+ // *.db/*.log
+ if strings.HasSuffix(p, ".db") || strings.HasSuffix(p, ".log") {
+ return true
+ }
+
// 用户家目录下的敏感目录(小写比较)
homePrefixes := []string{
strings.ToLower(filepath.Join(HomeDir, ".ssh")),
Source: GitHub Commit Details
Detection Methods for CVE-2026-41894
Indicators of Compromise
- HTTP requests to export endpoints containing double URL-encoded sequences such as %252e, %252f, or %255c
- Access logs showing requests attempting to reach siyuan.db, .log files, or parent directory paths through the export functionality
- Unusual file access patterns in SiYuan workspace directories from the web server process
- Authentication events followed immediately by export endpoint requests with encoded path characters
Detection Strategies
- Implement web application firewall (WAF) rules to detect double URL-encoded path traversal patterns (%25 followed by hex values)
- Monitor HTTP access logs for requests containing %252e%252e or similar double-encoded directory traversal sequences
- Configure intrusion detection systems to alert on export endpoint requests that contain unusual encoding patterns
- Review SiYuan kernel logs for "refuse to export" messages which may indicate exploitation attempts
Monitoring Recommendations
- Enable detailed logging for the SiYuan export functionality and monitor for anomalous access patterns
- Set up alerts for any access attempts to .db or .log files through web interfaces
- Monitor file system access patterns for the SiYuan process, specifically watching for reads outside the expected export directories
- Implement rate limiting on export endpoints to slow potential enumeration attacks
How to Mitigate CVE-2026-41894
Immediate Actions Required
- Upgrade SiYuan to version 3.6.5 or later immediately to address this vulnerability
- Review access logs for signs of exploitation, particularly requests containing double URL-encoded characters
- Restrict network access to SiYuan instances to trusted users and networks only
- Consider temporarily disabling the export functionality if immediate patching is not possible
Patch Information
The vulnerability is fixed in SiYuan version 3.6.5. The patch implements proper subpath validation using gulu.File.IsSubPath() to verify that resolved file paths remain within the intended export directory. Additionally, the sensitive path detection has been extended to explicitly block access to .db and .log files.
For detailed patch information, refer to:
Workarounds
- Restrict network access to SiYuan to localhost only or trusted internal networks using firewall rules
- Implement a reverse proxy with URL decoding normalization and path validation before requests reach SiYuan
- Remove or restrict access to the export endpoint at the web server level if not required
- Enable authentication enforcement and limit user accounts to only those who require access
# Example: Restrict SiYuan to localhost only using iptables
iptables -A INPUT -p tcp --dport 6806 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 6806 -j DROP
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


