Si Yuan, Path Traversal via Double URL Encoding, CVE-2026-41894 (Critical) -DC-Jul2026-865

Listen to this Post

CVE-2026-41894 is a critical path traversal vulnerability found in Si Yuan, an open-source digital knowledge base software. The vulnerability exists in the publish mode—an anonymous, read-only HTTP endpoint that typically runs on port 6808. An unauthenticated remote attacker can exploit this flaw to read arbitrary files within the WorkspaceDir, including sensitive configuration files and databases.
The root cause lies in three independent flaws that combine to enable this attack. First, the `GetAssetAbsPath` function in `kernel/model/assets.go` performs a second URL decoding pass as a fallback mechanism, effectively re-introducing the double-decode primitive that was patched in the `/export/` route for CVE-2026-41894. When a request like `/assets/%252e%252e/%252e%252e/conf/conf.json` is made, the Gin router performs one URL decoding, turning `%252e` into %2e. The fallback then decodes `%2e` to `.` , allowing path traversal sequences to bypass initial sanitization.
Second, the `CheckAbsPathAccessableByPublishAccess` function in `kernel/model/publish_access.go` contains a dangerous fall-through logic. It returns `true` for any path outside the DataDir, even when that path remains inside the WorkspaceDir. This means files like conf/conf.json, temp/siyuan.db, and siyuan.log—all residing in WorkspaceDir—are accessible because they are outside DataDir. Third, the `IsSensitivePath()` denylist, which is applied to the `/export/` route, is never invoked for the `/assets/` handler, leaving the route completely unprotected against serving sensitive file types like .db, .log, or anything under the `conf/` directory.
The attack is verified against Si Yuan v3.6.5. A request to `GET /assets/%252e%252e/%252e%252e/conf/conf.json` returns HTTP 200 with the contents of conf.json, which contains the `accessAuthCode` SHA256 hash, API token, and sync keys. In contrast, the patched `/export/` route correctly returns HTTP 401 for the same payload, and a single-encoded request like `/assets/%2e%2e/conf/conf.json` returns HTTP 404, confirming the double-encoding nature of the exploit.
Compromise of the `accessAuthCode` or API token allows an attacker to escalate to authenticated kernel API access, enabling full read/write operations on all notebooks. Compromise of sync credentials (S3/WebDAV) extends the attack beyond the host. The fix involves removing the `url.PathUnescape` fallback, replacing the dangerous fall-through with an explicit allowlist, and applying `IsSensitivePath()` to the `/assets/` handler as defense-in-depth.

DailyCVE Form:

Platform: Si Yuan
Version: 3.6.5
Vulnerability: Path Traversal
Severity: Critical
date: 2026-07-10

Prediction: 2026-07-17

What Undercode Say:

Verify vulnerability - conf.json exposure
curl -i "http://victim:6808/assets/%252e%252e/%252e%252e/conf/conf.json"
Expected: HTTP/1.1 200 OK, returns conf.json with credentials
Verify patched /export/ route (returns 401)
curl -i "http://victim:6808/export/%252e%252e/%252e%252e/conf/conf.json"
Single-encoded attempt (returns 404)
curl -i "http://victim:6808/assets/%2e%2e/conf/conf.json"
Access other sensitive files
curl -i "http://victim:6808/assets/%252e%252e/%252e%252e/temp/siyuan.db"
curl -i "http://victim:6808/assets/%252e%252e/%252e%252e/siyuan.log"

Exploit:

The exploit leverages double URL encoding to bypass path traversal protections. The attacker sends a GET request to the publish endpoint (/assets/path) with `..` segments double-encoded as %252e%252e. The Gin router performs one URL decode, yielding %2e%2e, which `path.Clean` cannot collapse. The `GetAssetAbsPath` fallback then performs a second decode, turning `%2e%2e` into ... The resulting path is joined with `DataDir` and cleaned, resolving to files inside `WorkspaceDir` but outside DataDir. The `CheckAbsPathAccessableByPublishAccess` function returns `true` for paths outside DataDir, and `IsSensitivePath()` is never called, allowing the file to be served.

Protection:

  • Remove the `url.PathUnescape` fallback in `GetAssetAbsPath` (assets.go:548).
  • In CheckAbsPathAccessableByPublishAccess, replace the `IsSubPath(DataDir, …)` fall-through with an explicit allowlist permitting only `DataDir` and its publishable subtree, and always call IsSensitivePath().
  • Apply `IsSensitivePath()` inside the `/assets/path` handler in `serve.go` as defense-in-depth.

Impact:

  • Confidentiality: Unauthenticated attackers can read arbitrary files inside WorkspaceDir, including `conf/conf.json` (containing `accessAuthCode` SHA256, API token, S3/WebDAV sync credentials), temp/siyuan.db, temp/blocktree.db, `temp/asset_content.db` (full notebook content), and `siyuan.log` (internal paths, OS username, plugin info).
  • Escalation: Compromise of `accessAuthCode` or API token enables authenticated kernel API access, granting full read/write capabilities over all notebooks. Compromise of sync credentials can lead to further compromise beyond the host.
  • Availability: While primarily a read vulnerability, the exposure of database files and logs can facilitate further attacks that may impact availability.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top