CVE-2026-69086

CVE-2026-69086 is a high-severity path traversal vulnerability in github.com/siyuan-note/siyuan/kernel (go), affecting versions < 0.0.0-20260720151813-0f5a0e7c67b0. It is fixed in 0.0.0-20260720151813-0f5a0e7c67b0.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

SiYuan: Path Traversal via unvalidated avID in RenderAttributeView/AV read endpoints : reader-reachable cross-scope attribute-view disclosure

CVE: This vulnerability corresponds to CVE-2026-69086.

Four attribute-view read endpoints build a filesystem path from a caller-controlled id/avID and read it without confining the result to the attribute-view storage directory (DataDir/storage/av/). On the load (file-exists) code path there is no boundary check, so an avID containing ../ segments escapes storage/av/ and causes the kernel to read a .json file elsewhere in the workspace.

The endpoints require only CheckAuth, which the publish service's RoleReader token satisfies; when Publish.Auth.Enable is false the publish proxy uses the anonymous account, making the surface reachable with no credentials.

Details

Affected endpoints (all gated by CheckAuth only, no CheckAdminRole):

  • POST /api/av/renderAttributeView  → arg["id"]
  • POST /api/av/getAttributeViewKeysByIDarg["avID"]
  • POST /api/av/getAttributeViewKeys  → arg["id"]
  • POST /api/av/getCurrentAttrViewImagesarg["id"]

In model.RenderAttributeView (model/attribute_view_render.go), the only identifier guard ast.IsNodeIDPattern(avID) sits inside the if !filelock.IsExist(existPath) (create) branch:

existPath = GetAttributeViewDataPath(avID)      // path built from avID, no check
if !filelock.IsExist(existPath) {               // NOT-EXIST / CREATE branch
    if !createIfNotExist {
        return // NotFound
    }
    if !ast.IsNodeIDPattern(avID) {             // <-- ONLY id guard, create branch only
        return ErrInvalidID
    }
    // ... create ...
}
attrView, err = av.ParseAttributeView(avID)     // LOAD runs unconditionally

When the traversal avID resolves to a file that already exists, the !filelock.IsExist(...) condition is false, the entire block (including the line with ast.IsNodeIDPattern) is skipped, and control falls straight through to av.ParseAttributeView(avID). That function rebuilds the path via filepath.Join(DataDir, "storage", "av", avID+".json") and calls filelock.ReadFile with no filepath.Rel / IsSubPath / .. rejection:

// av.ParseAttributeView -> attributeViewDataPathByBox / GetAttributeViewDataPath
avJSONPath = filepath.Join(DataDir, "storage", "av", avID+".json")  // no boundary check
// -> parseAttributeViewByPathInBox(avJSONPath, boxID)
data, _ = filelock.ReadFile(avJSONPath)                             // SINK

filepath.Join cleans the path but does not reject .. segments, so it provides no containment. The three getAttributeView* endpoints call ParseAttributeView with no create branch at all, so they never even reach the ast.IsNodeIDPattern check same defect, same auth tier.

The root cause is that identifier validation is placed on a single code branch rather than confining the load to the AV base directory, so the load path reads a caller-controlled location.

PoC

Precondition: publish mode enabled (default port 6808); reachable by a RoleReader publish token, or anonymously when Publish.Auth.Enable is false.

A request to /api/av/renderAttributeView with an id composed of ../ path segments that resolves to an existing .json file outside DataDir/storage/av/ causes that file to be read and parsed instead of being rejected, because the identifier validation is only reached on the not-exist/create branch.

I have withheld the exact encoded id value from this draft to avoid publishing a live traversal against internet-exposed publish instances. I'm happy to provide the precise value and a screenshot privately in this thread on request.

Impact

An authenticated publish RoleReader or an anonymous client when publish auth is disabled can cause the kernel to read .json files outside the attribute-view directory. Because the loaded file is unmarshalled into the attribute-view structure, the reliable primitives are:

  1. Disclosure of attribute-view (database) content from other scopes/notebooks the reader is not authorized to see.
  2. A .json-path existence oracle for arbitrary workspace locations.

Files not conforming to the AV schema are read but reflect little content, and the .json suffix is force-appended, so this is not a general arbitrary-file read. No admin role, CSRF token, or write permission is required.

Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files. Typical impact: unauthorized file read or write outside the intended directory.

CVE-2026-69086 has a CVSS score of 7.7 (High). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.0.0-20260720151813-0f5a0e7c67b0); upgrading removes the vulnerable code path.

Affected versions

github.com/siyuan-note/siyuan/kernel (< 0.0.0-20260720151813-0f5a0e7c67b0)

Security releases

github.com/siyuan-note/siyuan/kernel → 0.0.0-20260720151813-0f5a0e7c67b0 (go)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Validate avID with ast.IsNodeIDPattern before path construction on all branches (move it ahead of FindAttributeViewPath / GetAttributeViewDataPath), or preferably, so every caller inherits it confine at the sink: in attributeViewDataPathByBox / GetAttributeViewDataPath, compute the joined path and reject it unless filepath.Rel(avBaseDir, cleaned) stays within avBaseDir (no leading ..). Sink-side confinement also covers the three getAttributeView* endpoints that never reach the create-branch guard.

Frequently Asked Questions

  1. What is CVE-2026-69086? CVE-2026-69086 is a high-severity path traversal vulnerability in github.com/siyuan-note/siyuan/kernel (go), affecting versions < 0.0.0-20260720151813-0f5a0e7c67b0. It is fixed in 0.0.0-20260720151813-0f5a0e7c67b0. Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files.
  2. How severe is CVE-2026-69086? CVE-2026-69086 has a CVSS score of 7.7 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of github.com/siyuan-note/siyuan/kernel are affected by CVE-2026-69086? github.com/siyuan-note/siyuan/kernel (go) versions < 0.0.0-20260720151813-0f5a0e7c67b0 is affected.
  4. Is there a fix for CVE-2026-69086? Yes. CVE-2026-69086 is fixed in 0.0.0-20260720151813-0f5a0e7c67b0. Upgrade to this version or later.
  5. Is CVE-2026-69086 exploitable, and should I be worried? Whether CVE-2026-69086 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether CVE-2026-69086 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix CVE-2026-69086? Upgrade github.com/siyuan-note/siyuan/kernel to 0.0.0-20260720151813-0f5a0e7c67b0 or later.

Stop the waste.
Protect your environment with Kodem.