Skip to content
Heist/ feed
Back to feed
MediumFix available

SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem

Type: advisorySources: OSV2 source records

### Summary `/api/file/getUniqueFilename` takes a path from the request body and passes it to a filesystem existence check with no validation, confinement or authorization. The response distinguishes paths that exist from paths that do not, so an anonymous reader in publish mode can probe arbitrary locations on the host, one request per probe. Files and directories both work. Every neighbouring file route either requires an administrator or confines the path first. ### Details **Route.** `kernel/api/router.go:289` on master, `:292` on the development branch, `CheckAuth` only. **Handler,** `kernel/api/file.go:84`, in full: ```go util.ParseJsonArgs(arg, ret, util.BindJsonArg("path", &filePath, true, true)) ret.Data = map[string]any{"path": util.GetUniqueFilename(filePath)} ``` **The argument binder does no path handling.** `util.BindJsonArg` (`kernel/util/net.go:365`) takes two booleans, `required` (the key must be present) and `rejectEmpty` (the value must be non-empty). That is its entire contract. There is no `filepath.Clean`, no workspace join, no traversal check. An absolute path outside the workspace reaches `gulu.File.IsExist` unmodified. **The oracle.** `util/file.go:67`: ```go if !gulu.File.IsExist(filePath) { return filePath } // otherwise loop, returning the first non-existent dir/base (i).ext ``` Input echoed back means the path does not exist. A `(1)` suffix means it does. **The asymmetry.** | Route | Middleware | |---|---| | `putFile`, `copyFile`, `globalCopyFiles

Products
github.com/siyuan-note/siyuan/kernel
Affected versions
Not specified
Fixed versions
0.0.0-20260812083335-251596fc0de2
CVEs
CVE-2026-73605
Confirmed fixed CVEs
Not specified
Updated in this feed
28 Oct 2026, 08:46 UTC · Revision 1

Source evidence

SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem

core-osv · Original source

Published 1 Oct 2026, 15:46 UTC

### Summary `/api/file/getUniqueFilename` takes a path from the request body and passes it to a filesystem existence check with no validation, confinement or authorization. The response distinguishes paths that exist from paths that do not, so an anonymous reader in publish mode can probe arbitrary locations on the host, one request per probe. Files and directories both work. Every neighbouring file route either requires an administrator or confines the path first. ### Details **Route.** `kernel/api/router.go:289` on master, `:292` on the development branch, `CheckAuth` only. **Handler,** `kernel/api/file.go:84`, in full: ```go util.ParseJsonArgs(arg, ret, util.BindJsonArg("path", &filePath, true, true)) ret.Data = map[string]any{"path": util.GetUniqueFilename(filePath)} ``` **The argument binder does no path handling.** `util.BindJsonArg` (`kernel/util/net.go:365`) takes two booleans, `required` (the key must be present) and `rejectEmpty` (the value must be non-empty). That is its entire contract. There is no `filepath.Clean`, no workspace join, no traversal check. An absolute path outside the workspace reaches `gulu.File.IsExist` unmodified. **The oracle.** `util/file.go:67`: ```go if !gulu.File.IsExist(filePath) { return filePath } // otherwise loop, returning the first non-existent dir/base (i).ext ``` Input echoed back means the path does not exist. A `(1)` suffix means it does. **The asymmetry.** | Route | Middleware | |---|---| | `putFile`, `copyFile`, `globalCopyFiles

osv:GHSA-hf8h-97gm-4x2p

github.com/siyuan-note/siyuan/kernel

Fixed versions: 0.0.0-20260812083335-251596fc0de2

Complete source record
{
  "id": "d64f1c5e09dd7493994943bd114abc7b5cc5c9a1e3ef4ebc0eb6a4ae77b268b6",
  "url": "https://osv.dev/vulnerability/GHSA-hf8h-97gm-4x2p",
  "method": "structured",
  "payload": {
    "kind": "advisory",
    "title": "SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem",
    "summary": "### Summary `/api/file/getUniqueFilename` takes a path from the request body and passes it to a filesystem existence check with no validation, confinement or authorization. The response distinguishes paths that exist from paths that do not, so an anonymous reader in publish mode can probe arbitrary locations on the host, one request per probe. Files and directories both work. Every neighbouring file route either requires an administrator or confines the path first. ### Details **Route.** `kernel/api/router.go:289` on master, `:292` on the development branch, `CheckAuth` only. **Handler,** `kernel/api/file.go:84`, in full: ```go util.ParseJsonArgs(arg, ret, util.BindJsonArg(\"path\", &filePath, true, true)) ret.Data = map[string]any{\"path\": util.GetUniqueFilename(filePath)} ``` **The argument binder does no path handling.** `util.BindJsonArg` (`kernel/util/net.go:365`) takes two booleans, `required` (the key must be present) and `rejectEmpty` (the value must be non-empty). That is its entire contract. There is no `filepath.Clean`, no workspace join, no traversal check. An absolute path outside the workspace reaches `gulu.File.IsExist` unmodified. **The oracle.** `util/file.go:67`: ```go if !gulu.File.IsExist(filePath) { return filePath } // otherwise loop, returning the first non-existent dir/base (i).ext ``` Input echoed back means the path does not exist. A `(1)` suffix means it does. **The asymmetry.** | Route | Middleware | |---|---| | `putFile`, `copyFile`, `globalCopyFiles",
    "evidence": "osv:GHSA-hf8h-97gm-4x2p",
    "products": [
      {
        "name": {
          "value": "github.com/siyuan-note/siyuan/kernel",
          "evidence": "/affected/0/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "0.0.0-20260812083335-251596fc0de2",
            "evidence": "/affected/0/ranges"
          }
        ],
        "affected_versions": []
      }
    ],
    "severity": "medium",
    "structured": {
      "id": "GHSA-hf8h-97gm-4x2p",
      "aliases": [
        "CVE-2026-73605",
        "GHSA-hf8h-97gm-4x2p",
        "GO-2026-6626"
      ],
      "metrics": [
        {
          "type": "CVSS_V3",
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N"
        }
      ],
      "affected": [
        {
          "ranges": [
            {
              "type": "SEMVER",
              "events": [
                {
                  "introduced": "0"
                },
                {
                  "fixed": "0.0.0-20260812083335-251596fc0de2"
                }
              ]
            }
          ],
          "package": {
            "name": "github.com/siyuan-note/siyuan/kernel",
            "purl": "pkg:golang/github.com/siyuan-note/siyuan/kernel",
            "ecosystem": "Go"
          },
          "database_specific": {
            "source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-hf8h-97gm-4x2p/GHSA-hf8h-97gm-4x2p.json"
          }
        }
      ],
      "modified": "2026-10-07T17:55:29.509304430Z",
      "provider": "osv",
      "references": [
        "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-hf8h-97gm-4x2p",
        "https://nvd.nist.gov/vuln/detail/CVE-2026-73605",
        "https://github.com/siyuan-note/siyuan",
        "https://www.vulncheck.com/advisories/siyuan-before-path-traversal-via-getuniquefilename"
      ],
      "provider_metadata": {
        "cwe_ids": [
          "CWE-862"
        ],
        "severity": "MODERATE",
        "github_reviewed": true,
        "nvd_published_at": null,
        "github_reviewed_at": "2026-10-01T15:46:01Z"
      }
    },
    "related_cves": [
      {
        "value": "CVE-2026-73605",
        "evidence": "/aliases"
      }
    ],
    "security_relevant": true,
    "severity_evidence": "/severity/0/score"
  },
  "source_id": "core-osv",
  "document_id": 97116,
  "published_at": "2026-10-01T15:46:01+00:00"
}

SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem in github.com/siyuan-note/siyuan/ke

core-osv · Original source

Published 7 Oct 2026, 14:09 UTC

SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem in github.com/siyuan-note/siyuan/kernel

osv:GO-2026-6626

github.com/siyuan-note/siyuan/kernel

Fixed versions: 0.0.0-20260812083335-251596fc0de2

Complete source record
{
  "id": "b1bea559e274368a3f5921e091cc0c64cbf9f6f88e99f801b995e8ab59e0f23e",
  "url": "https://osv.dev/vulnerability/GO-2026-6626",
  "method": "structured",
  "payload": {
    "kind": "advisory",
    "title": "SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem in github.com/siyuan-note/siyuan/ke",
    "summary": "SiYuan: getUniqueFilename passes an unvalidated client-supplied path to the filesystem, giving anonymous readers an existence oracle over the entire host filesystem in github.com/siyuan-note/siyuan/kernel",
    "evidence": "osv:GO-2026-6626",
    "products": [
      {
        "name": {
          "value": "github.com/siyuan-note/siyuan/kernel",
          "evidence": "/affected/0/package/name"
        },
        "prerequisites": [],
        "fixed_versions": [
          {
            "value": "0.0.0-20260812083335-251596fc0de2",
            "evidence": "/affected/0/ranges"
          }
        ],
        "affected_versions": []
      }
    ],
    "severity": "unknown",
    "structured": {
      "id": "GO-2026-6626",
      "aliases": [
        "CVE-2026-73605",
        "GHSA-hf8h-97gm-4x2p",
        "GO-2026-6626"
      ],
      "affected": [
        {
          "ranges": [
            {
              "type": "SEMVER",
              "events": [
                {
                  "introduced": "0"
                },
                {
                  "fixed": "0.0.0-20260812083335-251596fc0de2"
                }
              ]
            }
          ],
          "package": {
            "name": "github.com/siyuan-note/siyuan/kernel",
            "purl": "pkg:golang/github.com/siyuan-note/siyuan/kernel",
            "ecosystem": "Go"
          },
          "database_specific": {
            "source": "https://vuln.go.dev/ID/GO-2026-6626.json"
          },
          "ecosystem_specific": {}
        }
      ],
      "modified": "2026-10-07T17:45:13.480332339Z",
      "provider": "osv",
      "references": [
        "https://github.com/siyuan-note/siyuan/security/advisories/GHSA-hf8h-97gm-4x2p",
        "https://nvd.nist.gov/vuln/detail/CVE-2026-73605",
        "https://www.vulncheck.com/advisories/siyuan-before-path-traversal-via-getuniquefilename"
      ],
      "provider_metadata": {
        "url": "https://pkg.go.dev/vuln/GO-2026-6626",
        "review_status": "UNREVIEWED"
      }
    },
    "related_cves": [
      {
        "value": "CVE-2026-73605",
        "evidence": "/aliases"
      }
    ],
    "security_relevant": true,
    "severity_evidence": null
  },
  "source_id": "core-osv",
  "document_id": 97106,
  "published_at": "2026-10-07T14:09:59+00:00"
}