CVE-2026-72794: SiYuan: CookieKey leak enables session forgery

GHSA-34fj-mwm6-fjfgHIGHPoC AVAILABLECISA: TRACK*
Published September 4, 2026
CISO Take

SiYuan's `/api/system/getConf` endpoint returns `CookieKey`, the secret used to HMAC-sign the app's session cookies, to any publish-mode reader — including anonymous visitors when `Publish.Auth.Enable` is false. This matters because the same codebase already treats this value as sensitive and strips it from the sibling `exportConf` endpoint, confirming the masking gap in `getConf` is a bug rather than a design choice, and because the key is a persistent credential: leaking it lets an attacker forge or tamper with session cookies the server accepts as authentic, and rotating it invalidates every active session rather than being a quiet fix. With 2,997 downstream dependents, an EPSS score in the top 84th percentile for near-term exploitation, and a single unauthenticated POST request as the full proof of concept, this is trivially weaponizable even though it isn't yet in CISA KEV and has no public exploit or Nuclei template. Teams running SiYuan in publish mode should upgrade past commit 77421530be4a immediately, and until patched, disable publish mode or enforce `Publish.Auth.Enable` with an access-auth code while watching for anomalous session activity on publish-facing accounts.

Sources:NVDGitHub AdvisoryEPSSOpenSSFvulncheck.comATLAS

What is the risk?

High severity (CVSS 8.6) with a low exploitation bar: a single unauthenticated POST request against a default, commonly-enabled feature (publish mode) is sufficient to obtain the credential. The unconditional impact — disclosure of the persistent session-signing key to any anonymous visitor or reader account — is present on every affected instance regardless of configuration. The ceiling (full privilege escalation to administrator) depends on the instance having no access-auth code configured or on other session-content checks being satisfiable, which is a common real-world deployment pattern for self-hosted note tools. EPSS sits at the 84th percentile, indicating meaningfully elevated likelihood of opportunistic scanning/exploitation relative to the broader CVE population, though it is not yet in CISA KEV and no public exploit or scanner template exists, so exploitation is plausible but not yet observed in the wild.

How does the attack unfold?

Initial Access
Attacker sends an unauthenticated POST to /api/system/getConf on a SiYuan instance running in publish mode.
AML.T0006
Credential Access
Response body includes the cleartext cookieKey field, the server's session-cookie HMAC signing secret.
AML.T0055
Defense Evasion / Privilege Escalation
Attacker forges a valid siyuan session cookie using the leaked key, and on instances without an access-auth code, escalates to an administrator session.
AML.T0012
Impact
Attacker gains persistent unauthorized access to notebooks, configuration, and connected AI-assisted features, surviving until the key is rotated and all sessions invalidated.
AML.T0048.003

What systems are affected?

PackageEcosystemVulnerable RangePatched
Jupyter Notebookgo< 0.0.0-20260725123945-77421530be4a0.0.0-20260725123945-77421530be4a
13.5KOpenSSF 5.83.0K dependentsPushed 3d ago79% patched~75d to patchFull package profile →

Do you use Jupyter Notebook? You're affected.

How severe is it?

CVSS 3.1
8.6 / 10
EPSS
0.3%
chance of exploitation in 30 days
Higher than 26% of all CVEs
Exploitation Status
Exploit Available
Exploitation: MEDIUM
Sophistication
Trivial
Exploitation Confidence
medium
○CISA SSVC: Public PoC
○Public PoC indexed (trickest/cve)
Composite signal derived from CISA KEV, VulnCheck KEV, CISA SSVC, EPSS, Metasploit, Exploit-DB, trickest/cve, Nuclei templates, and inthewild.io exploitation reports.

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRNone
UINone
SChanged
CHigh
INone
ANone

What should I do?

1 step
  1. Upgrade to the version at or after commit 77421530be4a, which fixes the masking gap. Until patched: disable publish mode entirely if not required, or set Publish.Auth.Enable=true and require a configured AccessAuthCode so a forged session cannot escalate to full administrator access. As a compensating control, treat the current CookieKey as compromised on any instance that has ever exposed getConf in publish mode — rotate it post-patch, which will invalidate all existing sessions (expected and necessary). Detection: audit reverse-proxy/access logs for POST requests to /api/system/getConf from unauthenticated or unexpected source IPs, and monitor for session cookies associated with accounts that never authenticated through the normal login flow.

What does CISA's SSVC say?

DecisionTrack*
Exploitationpoc
AutomatableYes
Technical Impactpartial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15-Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.3-AI system security controls
NIST AI RMF
MANAGE 4.1-AI system risk monitoring and response

Frequently Asked Questions

What is CVE-2026-72794?

SiYuan's `/api/system/getConf` endpoint returns `CookieKey`, the secret used to HMAC-sign the app's session cookies, to any publish-mode reader — including anonymous visitors when `Publish.Auth.Enable` is false. This matters because the same codebase already treats this value as sensitive and strips it from the sibling `exportConf` endpoint, confirming the masking gap in `getConf` is a bug rather than a design choice, and because the key is a persistent credential: leaking it lets an attacker forge or tamper with session cookies the server accepts as authentic, and rotating it invalidates every active session rather than being a quiet fix. With 2,997 downstream dependents, an EPSS score in the top 84th percentile for near-term exploitation, and a single unauthenticated POST request as the full proof of concept, this is trivially weaponizable even though it isn't yet in CISA KEV and has no public exploit or Nuclei template. Teams running SiYuan in publish mode should upgrade past commit 77421530be4a immediately, and until patched, disable publish mode or enforce `Publish.Auth.Enable` with an access-auth code while watching for anomalous session activity on publish-facing accounts.

Is CVE-2026-72794 actively exploited?

Proof-of-concept exploit code is publicly available for CVE-2026-72794, increasing the risk of exploitation.

How to fix CVE-2026-72794?

Upgrade to the version at or after commit 77421530be4a, which fixes the masking gap. Until patched: disable publish mode entirely if not required, or set `Publish.Auth.Enable=true` and require a configured `AccessAuthCode` so a forged session cannot escalate to full administrator access. As a compensating control, treat the current `CookieKey` as compromised on any instance that has ever exposed `getConf` in publish mode — rotate it post-patch, which will invalidate all existing sessions (expected and necessary). Detection: audit reverse-proxy/access logs for POST requests to `/api/system/getConf` from unauthenticated or unexpected source IPs, and monitor for session cookies associated with accounts that never authenticated through the normal login flow.

What systems are affected by CVE-2026-72794?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, self-hosted knowledge management / RAG source systems.

What is the CVSS score for CVE-2026-72794?

CVE-2026-72794 has a CVSS v3.1 base score of 8.6 (HIGH). The EPSS exploitation probability is 0.33%.

What is the AI security impact?

Affected AI Architectures

agent frameworksself-hosted knowledge management / RAG source systems

MITRE ATLAS Techniques

AML.T0012Valid Accounts
AML.T0055Unsecured Credentials

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: A.6.2.3
NIST AI RMF: MANAGE 4.1

What are the technical details?

Original Advisory

**CVE:** This vulnerability corresponds to [CVE-2026-72794](https://nvd.nist.gov/vuln/detail/CVE-2026-72794). ### Summary `/api/system/getConf` returns `Conf.CookieKey`, the key used to sign the server's session cookies in its response body. The endpoint is registered with `CheckAuth` only, so the field reaches the publish `RoleReader` token and the anonymous account when `Publish.Auth.Enable` is `false`. The configuration-export endpoint in the same file strips this exact field before returning config, so the project already treats it as secret. The reader-facing masking path does not. ### Details | Item | Detail | |---|---| | Route | `kernel/api/router.go:70` `POST /api/system/getConf` → `model.CheckAuth` → `getConf` | | Middleware | `CheckAuth` only — no `CheckReadonly`, no `CheckAdminRole` | | Leaked field | `AppConf.CookieKey`, serialized as `cookieKey` | | Purpose of the field | Signing key for the `siyuan` session cookie | **The field survives every stage of the masking chain.** `getConf` masks through `GetMaskedConf()` → `HideConfSecret()` (non-administrators) → `FilterConfByPublishIgnore()` (readers) → the browser-side System-path strip. `CookieKey` is removed by none of them: - `GetMaskedConf` masks `UserData`, `MCPOAuth` and `AccessAuthCode` only. - `HideConfSecret` nulls `AI`, `Api`, `Flashcard`, `ServerAddrs`, `Publish`, `Repo`, `Sync`, `Secrets`, `Variables` and the System paths. It contains no reference to `CookieKey`. - `FilterConfByPublishIgnore` touches `UILayout` only. - The browser-side strip removes System paths only. **The key is live, not vestigial.** It is passed straight into the session store at startup: ``` cli/cmd/serve.go:67 go server.Serve(false, model.Conf.CookieKey) kernel/server/serve.go:152 sessionStore = cookie.NewStore([]byte(cookieKey)) kernel/server/serve.go:159 ginServer.Use(sessions.Sessions("siyuan", sessionStore)) ``` `gin-contrib/sessions/cookie.NewStore` constructed with a single key uses that key as the `gorilla/securecookie` HMAC key. The `siyuan` session cookie is therefore signed with the value the endpoint hands out. An attacker holding it can mint and modify session cookies that the server accepts as authentic. **Guarded sibling, in the same file.** `exportConf` (`kernel/api/system.go:299`) clones the configuration before returning it and explicitly clears both secrets: ``` kernel/api/system.go:360 clonedConf.CookieKey = "" clonedConf.NotebookCrypto = nil ``` The project has already classified `CookieKey` as a value that must not leave the server. The `getConf` masking path omits the same field. **Ceiling is environment-dependent, floor is not.** Escalating a forged session to administrator additionally requires the forged `SessionData` to carry the matching `AccessAuthCode`, which `GetMaskedConf` does mask or the instance to have no access-auth code configured, which is a common deployment. The unconditional impact, present on every instance, is the disclosure of a persistent cryptographic secret to an unauthenticated party together with the cookie-forgery capability that follows from it. Rotating the key invalidates all existing sessions, so this is not a secret that can be quietly refreshed. ### Proof of Concept Precondition: publish mode enabled (default port 6808); anonymous when `Publish.Auth.Enable` is `false`, otherwise any publish reader account. ``` POST http://127.0.0.1:6808/api/system/getConf {} → 200 The response body's conf object contains a cookieKey field holding the server's session-signing key in cleartext. ``` Differential check against the endpoint that does strip it: ``` POST http://127.0.0.1:6808/api/system/exportConf → cookieKey is empty, notebookCrypto is null ``` The same value is withheld by one endpoint and returned by the other. ### Impact An anonymous reader in publish mode or any publish `RoleReader` obtains the server's session-cookie signing key. This is a persistent cryptographic secret whose disclosure cannot be remediated without invalidating every active session. Possession of the key permits forging and tampering with `siyuan` session cookies that the server will validate as authentic. On instances with no access-auth code configured, or where a forged session's contents otherwise satisfy the server's checks, this extends to authenticating as a privileged user. ### Suggested fix Clear `CookieKey` in `HideConfSecret` for all non-administrator responses. The more durable fix is to route non-administrator `getConf` through the `exportConf` cloner, which already handles `CookieKey`, `NotebookCrypto`, `Account`, `Stat`, `System.ID`, `Export.PandocBin` and the AI keys replacing the current blocklist, which fails open on every field nobody thought to add, with the allowlist-style cloner the project already maintains.

Exploitation Scenario

An attacker discovers a SiYuan instance running in publish mode (default port 6808) exposed to the internet, a common configuration for teams sharing a public knowledge base. Without authenticating, the attacker sends a single `POST /api/system/getConf` request and extracts the `cookieKey` field from the response — the server's HMAC key for signing `siyuan` session cookies. Using this key, the attacker crafts a forged session cookie with `gorilla/securecookie`-compatible signing and submits it to the server. If the instance has no `AccessAuthCode` configured (a common default for personal/team deployments), the forged session is accepted as an authenticated administrator, giving the attacker full read/write access to all notebooks, configuration, and any AI-assisted features tied to the account — all without ever needing valid credentials.

Weaknesses (CWE)

CWE-522 — Insufficiently Protected Credentials: The product transmits or stores authentication credentials, but it uses an insecure method that is susceptible to unauthorized interception and/or retrieval.

  • [Architecture and Design] Use an appropriate security mechanism to protect the credentials.
  • [Architecture and Design] Make appropriate use of cryptography to protect the credentials.

Source: MITRE CWE corpus.

CVSS Vector

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

Timeline

Published
September 4, 2026
Last Modified
September 4, 2026
First Seen
September 5, 2026

Related Vulnerabilities