KEVWire

Security intelligence, with context.

Response snapshot Oct 26, 2026, 23:32 UTC

Back to the wire
Permalink
VulnerabilityCVE-2026-73630

SiYuan: authFilePublishAccess distinguishes hidden and forbidden documents from public and nonexistent ones, and issues a publish-auth cookie for documents it reports as forbidden

`/api/filetree/authFilePublishAccess` is registered with `CheckAuth` only and is reachable anonymously. It never sets a failure code, so its outcome is signalled entirely by the response message and by whether a `Set-Cookie` header is present.

At a glance

Exploited
Not known
Severity
5.8 Medium (CVSS 3.1)
Chance of exploitation
0.3% in the next 30 days
Sources
1 source

What to do

GitHub lists first patched versions: github.com/siyuan-note/siyuan/kernel: 0.0.0-20260731093152-c7522b8db586. Confirm the affected range and upgrade guidance in the exact advisory.

Read GitHub-reviewed advisory GHSA-4pjg-x8qj-33j5 (opens a new tab)

What happened

### Summary

`/api/filetree/authFilePublishAccess` is registered with `CheckAuth` only and is reachable anonymously. It never sets a failure code, so its outcome is signalled entirely by the response message and by whether a `Set-Cookie` header is present.

Those two signals differ across access tiers, which lets an anonymous caller determine, for any candidate document identifier, whether that document is public or nonexistent, password-protected, or exists at the hidden or forbidden tier.

Separately, hidden and forbidden entries carry an empty password. Submitting `password:""` therefore satisfies the equality check for them, and the server responds by issuing `Set-Cookie: publish-auth- ` for a document whose own tier is forbidden.

Continue reading

### Details

**Route,** identical on both refs:

```go ginServer.Handle("POST", "/api/filetree/authFilePublishAccess", model.CheckAuth, authFilePublishAccess) ```

No `CheckAdminRole`, no `CheckReadonly`.

**Handler,** `kernel/api/filetree.go:1608` on the development branch and `:1421` on master. `ret.Code` is never assigned on the failure path, so every response carries `code:0`. The branch is:

```go if item.Password == password { // SetPublishAuthCookie } else { ret.Msg = Conf.Language(285) } ```

**The cookie is issued for forbidden documents.** Entries at the hidden and forbidden tiers store `Password == ""`. A request with `password:""` therefore makes `item.Password == password` true for them, and the handler takes the success branch. The server issues a publish-auth cookie for a document it otherwise treats as inaccessible.

The cookie itself confers nothing, because those tiers are decided before any password check elsewhere in the codebase. The defect is that the endpoint's success signal does not correspond to access being granted, and that signal is observable.

**Three distinguishable outcomes.** With `password:""`, one request per candidate identifier:

| Tier of the target | `Set-Cookie` | Body | |---|---|---| | Public (no publish-access entry) | absent | `{"code":0,"msg":""}` | | Nonexistent identifier | absent | `{"code":0,"msg":""}` | | Password-protected | absent | `{"code":0,"msg":"Password is incorrect"}` | | Hidden | **present** | `{"code":0,"msg":""}` | | Forbidden | **present** | `{"code":0,"msg":""}` |

Public and nonexistent are indistinguishable from each other, which is correct. Everything else separates. A caller learns whether a given identifier names a password-protected document, or a document that exists at the hidden or forbidden tier, which is precisely the class the publish tiers exist to conceal.

**Identifiers are readily available.** Document and block identifiers appear in the DOM of published pages, in reference and backlink payloads, and in annotation reference data. The caller does not need to guess them.

**A fourth response on the development branch.** `IsEncryptedPublishRuntimeTarget` sets `ret.Code = -1`, which identifies the supplied identifier as belonging to an encrypted notebook. That is a membership oracle for encrypted notebooks, the same data class as `GHSA-f2rw-w22v-54vh`.

### Proof of Concept

Publish mode enabled, `Publish.Auth.Enable` false, anonymous client. One request per candidate identifier, all with an empty password:

``` POST /api/filetree/authFilePublishAccess {"id":" ","password":""} ```

Comparing the response message and the presence of `Set-Cookie` against the table above classifies the identifier. Documents at the hidden and forbidden tiers return a publish-auth cookie and an empty message, distinguishing them both from public documents and from identifiers that name nothing at all.

### Impact

An anonymous reader in publish mode, or any publish `RoleReader`, can classify arbitrary document identifiers by access tier and confirm the existence of documents at the hidden and forbidden tiers. On the development branch the same endpoint additionally reveals whether an identifier belongs to an encrypted notebook.

Scoped precisely: no document content is disclosed and no privilege is gained, since the issued cookie is inert for these tiers. The value is as a confirmation primitive, turning an identifier obtained elsewhere into a definite statement about a document the reader is not permitted to see.

Confidentiality only, with no integrity or availability impact.

### Suggested fix

Return an identical response for every failure and for every tier the caller may not access, with no `Set-Cookie` header and no distinguishing message. In particular, do not treat an empty stored password as a successful match: hidden and forbidden entries should short-circuit before the password comparison rather than satisfying it. The encrypted-notebook branch should return the same generic response as everything else rather than its own code.

A rate limit on this endpoint would be a reasonable additional hardening measure, though it does not address the disclosure above.

Affected package ranges reported by GitHub: github.com/siyuan-note/siyuan/kernel: < 0.0.0-20260731093152-c7522b8db586

Scores and how they were measured

CVSS base severity

5.8

Version 3.1As of

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N

Measurement source (opens a new tab)

How bad it is if exploited. Not a prediction of exploitation or proof you are exposed.

EPSS probability

0.3%

Scored Percentile 27.6%

Model and measurement source (opens a new tab)

A model's estimate of exploitation in the next 30 days, not certainty or your own risk.

Related technology

Sources

  1. Primary source

    GitHub-reviewed advisory GHSA-4pjg-x8qj-33j5 (opens a new tab)

    The public advisory supplies the description, affected package/version ranges, and any listed CVSS metric. GitHub review is not local review.

    Published Checked

  2. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  3. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  4. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  5. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  6. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  7. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  8. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  9. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  10. Primary source

    GitHub public advisory API page (opens a new tab)

    The API page supplied GHSA-4pjg-x8qj-33j5, its actual identifiers, source dates, and structured metrics.

    Published Date not suppliedChecked

  11. Primary source

    FIRST measured EPSS score (opens a new tab)

    Measured EPSS probability and percentile for CVE-2026-73630, scored 2026-10-26. This is a model estimate, not proof of exposure.

    Published Checked

Cite this record

For factual claims, cite the primary sources above; cite KEVWire for its compilation, dates, and classifications.

APA

KEVWire. (2026, October 23). SiYuan: authFilePublishAccess distinguishes hidden and forbidden documents from public and nonexistent ones, and issues a publish-auth cookie for documents it reports as forbidden (CVE-2026-73630). https://kevwire.com/record/CVE-2026-73630

MLA

"SiYuan: authFilePublishAccess distinguishes hidden and forbidden documents from public and nonexistent ones, and issues a publish-auth cookie for documents it reports as forbidden (CVE-2026-73630)." KEVWire, 23 Oct. 2026, kevwire.com/record/CVE-2026-73630.

Chicago

KEVWire. "SiYuan: authFilePublishAccess distinguishes hidden and forbidden documents from public and nonexistent ones, and issues a publish-auth cookie for documents it reports as forbidden (CVE-2026-73630)." Last modified October 23, 2026. https://kevwire.com/record/CVE-2026-73630.

Evidence summary (plain text)

SiYuan: authFilePublishAccess distinguishes hidden and forbidden documents from public and nonexistent ones, and issues a publish-auth cookie for documents it reports as forbidden (Oct 23, 2026).
`/api/filetree/authFilePublishAccess` is registered with `CheckAuth` only and is reachable anonymously. It never sets a failure code, so its outcome is signalled entirely by the response message and by whether a `Set-Cookie` header is present. Those two signals differ across access tiers, which lets an anonymous caller determine, for any candidate document identifier, whether that document is public or nonexistent, password-protected, or exists at the hidden or forbidden tier.

Separately, hidden and forbidden entries carry an empty password. Submitting `password:""` therefore satisfies the equality check for them, and the server responds by issuing `Set-Cookie: publish-auth- ` for a document whose own tier is forbidden.
CVSS 5.8 (version 3.1; evidence as of Oct 23, 2026; https://github.com/advisories/GHSA-4pjg-x8qj-33j5).
EPSS 0.3% for the following 30 days, scored Oct 26, 2026 (https://api.first.org/data/v1/epss?cve=CVE-2026-73630&date=2026-10-26).
Sources:
GitHub-reviewed advisory GHSA-4pjg-x8qj-33j5: https://github.com/advisories/GHSA-4pjg-x8qj-33j5
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo1MTozMFrOAAf0Mg%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0OToxMlrOAAf0LQ%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0NzoxN1rOAAf0Kg%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0NTozNlrOAAf0Jw%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0NTowNVrOAAf0JQ%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0Mzo0NVrOAAf0Iw%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QyMDo0MzozMVrOAAf0Ig%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc&after=Y3Vyc29yOnYyOpK0MjAyNi0xMC0yM1QxODozNTowMVrOAAZRcw%3D%3D
GitHub public advisory API page: https://api.github.com/advisories?type=reviewed&per_page=100&sort=updated&direction=desc
FIRST measured EPSS score: https://api.first.org/data/v1/epss?cve=CVE-2026-73630&date=2026-10-26
Record ID: CVE-2026-73630.
Record origin: Ingested record.
AI evidence: Not assessed.
Known exploitation: Not assessed.
Zero-day status: Not assessed. KEV membership alone does not establish zero-day status.
About this data

This record was ingested from a data source. Retrieved: Oct 26, 2026, 19:40 UTC. Ingestion is not an independent editorial investigation.

A CISA KEV listing documents known exploitation, not necessarily a zero-day; absence from the catalog does not prove a vulnerability has never been exploited.

Technology tags indicate possible relevance, not verified exposure. Confirm the affected product, version, and configuration against your own inventory; KEVWire does not scan your systems.

A personal reading checklist on this device, not verified remediation.

Record JSON

Your account

Email alerts

Email alerts are not available yet. To follow your stack today, use its RSS feed, which honors your filters, or connect an AI agent through the API.

Suggest an improvement

Ideas, missing sources, corrections, and bugs are all welcome. No account needed. Suggestions are reviewed by a person before anything changes.

Record details

Record detail