Skip to content

CVE-2026-66012: Verified Reproduction

CVE-2026-66012: SiYuan missing authorization in /mcp enables unauthenticated administrator takeover via Publish proxy

CVE-2026-66012 is verified against siyuan · github. Affected versions: before 3.7.2 (specifically 3.7.1 per advisory). This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00305.

REPRO-2026-00305 siyuan · github Jul 27, 2026 CVE entry ↗ .txt
Severity
CRITICAL
Confidence
HIGH
Reproduced in
171m 57s
Tool calls
853
Spend
$57.52
01 · Overview

What Is CVE-2026-66012?

CVE-2026-66012 is a critical-severity vulnerability affecting siyuan before 3.7.2 (specifically 3.7.1 per advisory). Pruva has independently reproduced it and publishes a verified, runnable proof-of-concept (reproduction REPRO-2026-00305).

02 · Severity & CVSS

CVE-2026-66012 Severity

CVE-2026-66012 is rated critical severity.

CRITICAL threat level
Weakness CWE-862 Missing Authorization — Missing Authorization

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

03 · Affected Versions

Affected siyuan Versions

siyuan · github versions before 3.7.2 (specifically 3.7.1 per advisory) are affected.

How to Reproduce CVE-2026-66012

$ pruva-verify REPRO-2026-00305
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00305/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-66012

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

Unauthenticated JSON-RPC POST /mcp tool calls through the Publish reverse proxy, including file writes for plugin.json, index.js, and petals.json

Attack chain
  1. POST /mcp via anonymous Publish proxy; MCP file write plants desktop plugin; real SiYuan Electron desktop loads plugin on next launch
How the agent worked 2,001 events · 853 tool calls · 2h 52m
2h 52mDuration
853Tool calls
487Reasoning steps
2,001Events
64Dead-ends
Agent activity over 2h 52m
Policy
1
Support
12
Repro
1,491
Judge
188
Variant
305
0:00171:57

Root Cause and Exploit Chain for CVE-2026-66012

Versions: Before 3.7.2. The reproduction uses vulnerable v3.7.1 and fixed v3.7.2.

SiYuan versions before 3.7.2 expose the management-grade MCP endpoint through the Publish reverse proxy when Publish is enabled in anonymous mode. An unauthenticated remote HTTP client can POST to /mcp on the Publish port, obtain an MCP session, and invoke the built-in file tool. That tool can read and write workspace files, including conf/conf.json and plugin configuration under data/plugins and data/storage/petal. In this run the unauthenticated MCP write primitive is chained into code execution by planting a desktop plugin in the workspace, restarting/launching the real SiYuan Electron desktop runtime under Xvfb, and capturing attacker-controlled id command output from the plugin's renderer-side JavaScript.

  • Package/component affected: SiYuan kernel MCP service, Publish reverse proxy, workspace file tooling, and desktop plugin loader.
  • Affected versions: Before 3.7.2. The reproduction uses vulnerable v3.7.1 and fixed v3.7.2.
  • Risk level and consequences: Critical. With Publish anonymous mode enabled and reachable, an unauthenticated remote attacker can use /mcp to read workspace files, exfiltrate conf/conf.json, write arbitrary workspace files, plant plugins, and obtain command execution when the real desktop/Electron runtime next loads the planted plugin. Publish authentication enabled or v3.7.2 blocks the unauthenticated /mcp path.

Impact Parity

  • Disclosed/claimed maximum impact: Unauthenticated administrator takeover / code execution through Publish-proxied /mcp, with workspace file read/write, secret exfiltration, plugin planting, and execution on next desktop launch.
  • Reproduced impact from this run: Full unauthenticated HTTP access to /mcp through the Publish reverse proxy on v3.7.1; unauthorized file write/read; conf/conf.json exfiltration; plugin files and petals.json planted using the same unauthenticated /mcp session; real SiYuan Electron desktop launched under Xvfb; planted plugin executes attacker-controlled JavaScript with Node/Electron child_process access and writes a marker containing id output. Fixed v3.7.2 and Publish-auth-enabled controls reject the initial unauthenticated /mcp request and therefore block the planting path.
  • Parity: full.
  • Not demonstrated: Interactive administrator UI takeover is not separately demonstrated because the reproduced attacker-controlled command execution is a stronger concrete runtime effect than file-only takeover. The command executes as the SiYuan desktop user inside the tested Linux sandbox.

Root Cause

Before v3.7.2, the /mcp route was reachable after the Publish reverse proxy applied the anonymous Publish access context. The MCP server exposed tools that are equivalent to local/admin workspace management primitives, including arbitrary workspace file read/write. In anonymous Publish mode, the reverse proxy allowed unauthenticated clients to reach /mcp; the MCP handler accepted initialize and subsequent tools/call requests without enforcing an administrator role for this management surface. Because the file tool accepts attacker-controlled paths inside the workspace, an unauthenticated client can write plugin files under data/plugins/<name>/ and enable the plugin via data/storage/petal/petals.json.

The desktop plugin loader later loads enabled plugins from those workspace files. In the desktop renderer, SiYuan v3.7.1 creates BrowserWindows with nodeIntegration: true and contextIsolation: false; plugin JavaScript is evaluated via the plugin loader and can call Node/Electron modules. Therefore, a planted plugin can call require("child_process") and execute a local command when the real desktop application starts with that workspace.

The v3.7.2 fix adds authorization requirements to MCP. In the fixed source, the MCP routes are registered with model.CheckAuth, model.CheckAdminRole, and model.CheckReadonly, so Publish anonymous access no longer satisfies the admin requirement for /mcp. Public references include the advisory and fixed release/commit listed in the ticket: https://github.com/siyuan-note/siyuan/security/advisories/GHSA-cvhv-7xhj-xjp8 and SiYuan v3.7.2.

Reproduction Steps

  1. Run bundle/repro/reproduction_steps.sh.
  2. The script reuses or creates the SiYuan checkout in the prepared project cache, builds the real v3.7.1 and v3.7.2 kernels, ensures the real v3.7.1 Linux desktop release is available, starts the vulnerable v3.7.1 kernel with Publish anonymous mode enabled, and sends HTTP requests to POST /mcp through the real Publish reverse proxy at 127.0.0.1:6808.
  3. The script obtains an unauthenticated MCP session, writes and reads pwned.txt, exfiltrates conf/conf.json, plants a desktop plugin and petals.json via the MCP file tool, stops the kernel, and launches the real SiYuan Electron desktop under Xvfb with the same workspace. The plugin writes a marker containing id output to bundle/logs/repro/desktop-rce-marker.log.
  4. The script also runs negative controls: v3.7.1 with Publish auth enabled rejects unauthenticated /mcp, and v3.7.2 with anonymous Publish rejects the initial /mcp request before any plugin planting can occur.

Expected evidence is a successful script exit, vulnerable /mcp response logs containing file written, owned by unauthenticated mcp, and kernelVersion, the desktop marker containing PRUVA_MCP_DESKTOP_RCE plus uid=..., and fixed/auth-control logs showing HTTP 401/403 style rejection of unauthenticated /mcp.

Evidence

The reproduction script writes all runtime-backed evidence under bundle/logs/repro/ and records the proof artifacts in bundle/repro/runtime_manifest.json. Key artifacts include:

  • bundle/logs/repro/mcp-init-response.log — unauthenticated POST /mcp initialize through the Publish reverse proxy returns HTTP 200 and Mcp-Session-Id on v3.7.1.
  • bundle/logs/repro/mcp-write-response.log — MCP file tool writes pwned.txt as an unauthenticated attacker.
  • bundle/logs/repro/mcp-read-response.log — MCP file tool reads back the attacker-controlled content.
  • bundle/logs/repro/mcp-conf-response.log — MCP file tool reads conf/conf.json from the workspace.
  • bundle/logs/repro/mcp-plugin-json-write-response.log, bundle/logs/repro/mcp-plugin-index-write-response.log, and bundle/logs/repro/mcp-petals-write-response.log — plugin planting performed through the same unauthenticated MCP session.
  • bundle/logs/repro/siyuan-desktop-rce.log and bundle/logs/repro/siyuan-desktop-rce-app.log — real Electron desktop launch under Xvfb with the planted workspace.
  • bundle/logs/repro/desktop-rce-marker.log — marker generated by attacker-planted plugin code, containing PRUVA_MCP_DESKTOP_RCE and id output.
  • bundle/logs/repro/siyuan-vuln-auth.log and bundle/logs/repro/mcp-auth-control-response.log — Publish authentication enabled blocks unauthenticated /mcp.
  • bundle/logs/repro/siyuan-fixed-anon.log and bundle/logs/repro/mcp-fixed-control-response.log — fixed v3.7.2 blocks the same unauthenticated /mcp request even with anonymous Publish enabled.

Environment details captured by the script include source tag/commit resolution, kernel build logs, real desktop release extraction, and runtime logs from the vulnerable and fixed kernels.

Recommendations / Next Steps

  • Upgrade SiYuan to v3.7.2 or later.
  • Keep Publish authentication enabled whenever Publish is exposed, and do not expose anonymous Publish to untrusted networks on affected versions.
  • Treat /mcp and similar file/plugin/workspace management routes as local/admin-only surfaces. Require an authenticated administrator role before dispatching MCP methods or tools.
  • Add regression tests that exercise /mcp through the Publish reverse proxy with anonymous Publish enabled, Publish auth enabled, and authenticated-admin contexts. The anonymous and non-admin cases must fail before MCP session creation and tool dispatch.
  • Consider defense in depth for plugin loading: explicit trust prompts, safer defaults for bazaar.trust, and stronger separation between remote content exposure and local plugin execution.

Additional Notes

  • The reproduction is idempotent: it uses fresh /tmp workspaces and marker paths, kills leftover SiYuan kernel/desktop processes before and after each attempt, and can be run repeatedly.
  • The desktop code-execution proof requires Linux GUI dependencies and Xvfb because it launches the real Electron product path. The script installs required packages when absent and uses the real upstream SiYuan v3.7.1 Linux desktop tarball.
  • The code-execution marker is generated only after the unauthenticated /mcp write primitive plants the plugin in the current run; it is not a pre-planted artifact.

CVE-2026-66012 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:20
0:00
session startedaccounts/fireworks/models/kimi-k2p7-code · CVE-2026-66012 · REPRO-20
0:07
0:08
0:13
0:14
web search
1:10
1:10
extract_facts
no facts extracted
1:11
1:11
1:11
supportclaim_contract
1:18
1:18
1:18
1:18
1:18
1:21
1:22
1:22
1:24
1:24
1:24
1:24
1:28
2:08
$mkdir -p /pruva/project-cache/repo-mirrors && git clone --mirror https://github.com/siyuan-note/siyuan.git /pruva/project-cache/repo-mirrors/siyuan.git 2>&1 | tail -20
39.6s
Cloning into bare repository '/pruva/project-cache/repo-mirrors/siyuan.git'...
2:10
web search
2:14
2:15
$git clone --local --shared /pruva/project-cache/repo-mirrors/siyuan.git /pruva/project-cache/repo 2>&1 | tail -10 && cd /pruva/project-cache/repo && git fetch --tags origin 2>&1 | tail -5 && git rev-parse c72ca4cd09019e5f64afdee8f8c6ec5ef34858db && git rev-parse v3.7.2
1.0s
Cloning into '/pruva/project-cache/repo'...
done.
c72ca4cd09019e5f64afdee8f8c6ec5ef34858db
726dae1d518927f70ea609bc146288b9aa95e366
2:19
2:20
$cd /pruva/project-cache/repo && git merge-base --is-ancestor c72ca4cd09019e5f64afdee8f8c6ec5ef34858db v3.7.2 && echo 'c72ca4cd is ancestor of v3.7.2' || echo 'NOT ancestor' && git log --oneline -5 c72ca4cd09019e5f64afdee8f8c6ec5ef34858db && echo '---' && git log --oneline -5 v3.7.2
0.2s
c72ca4cd is ancestor of v3.7.2
c72ca4cd0 :memo: Update README
1f4a936df :art: https://github.com/siyuan-note/siyuan/issues/18069
563f1ec95 :art: https://github.com/siyuan-note/siyuan/issues/18069
c3bef7509 :memo: Update README
fef72d896 :art: https://github.com/siyuan-note/siyuan/issues/18016
---
726dae1d5 Merge remote-tracking branch 'origin/master'

Artifacts and Evidence for CVE-2026-66012

Scripts, logs, diffs, and output captured during the reproduction.

bundle/repro/exploit_knowledge.json18.1 KB
bundle/logs/repro/mcp-fixed-control-response.log0.1 KB
bundle/logs/repro/desktop-rce-marker-1785119719-59078.log0.1 KB
bundle/logs/repro/desktop-rce-marker-1785119775-59728.log0.1 KB
bundle/logs/repro/desktop-rce-marker-1785131179-1.log0.1 KB
bundle/logs/repro/desktop-rce-marker.log0.1 KB
bundle/logs/repro/escalation_experiment.log1.5 KB
bundle/logs/repro/escalation_experiment2.log1.5 KB
bundle/logs/repro/escalation-boot2.log2.7 KB
bundle/logs/repro/escalation-plugin-tool-response.log0.2 KB
bundle/logs/repro/escalation2-fetch-response.log0.2 KB
bundle/logs/repro/mcp-auth-control-response.log0.2 KB
bundle/logs/repro/mcp-conf-response.log12.4 KB
bundle/logs/repro/command-exec-negative-control.json0.2 KB
bundle/logs/repro/mcp-init-response.log0.6 KB
bundle/logs/repro/mcp-petals-write-response.log0.1 KB
bundle/logs/repro/mcp-plugin-index-write-response.log0.1 KB
bundle/logs/repro/mcp-plugin-json-write-response.log0.1 KB
bundle/logs/repro/mcp-read-response.log0.1 KB
bundle/logs/repro/mcp-write-response.log0.1 KB
bundle/logs/repro/reproduction_steps.log2.0 KB
bundle/logs/repro/siyuan-desktop-rce-app.log1.4 KB
bundle/logs/repro/siyuan-desktop-rce.log4.8 KB
bundle/logs/repro/siyuan-fixed-anon.log2.4 KB
bundle/logs/repro/siyuan-vuln-anon.log3.5 KB
bundle/logs/repro/siyuan-vuln-auth.log3.2 KB
bundle/logs/repro/source-v3.7.1-mcp-server.go3.4 KB
bundle/logs/repro/source-v3.7.2-mcp-server.go3.7 KB
bundle/repro/rca_report.md8.7 KB
bundle/repro/reproduction_steps.sh21.6 KB
bundle/repro/runtime_manifest.json1.6 KB
bundle/repro/validation_verdict.json0.8 KB
08 · How to Fix

How to Fix CVE-2026-66012

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-66012 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-66012

Is CVE-2026-66012 exploitable?

Yes. Pruva independently reproduced CVE-2026-66012 in siyuan and verified the exploit fires end-to-end in a sandboxed environment. A runnable proof-of-concept script and the full agent transcript are on this page (reproduction REPRO-2026-00305).

How severe is CVE-2026-66012?

CVE-2026-66012 is rated critical severity.

What type of vulnerability is CVE-2026-66012?

CVE-2026-66012 is classified as CWE-862 Missing Authorization (Missing Authorization).

Which versions of siyuan are affected by CVE-2026-66012?

siyuan before 3.7.2 (specifically 3.7.1 per advisory) is affected by CVE-2026-66012.

How can I reproduce CVE-2026-66012?

Pruva provides a verified reproduction script on this page. Download it and run it inside an isolated environment such as a container or virtual machine — never against production. The reproduction was confirmed end-to-end by Pruva's automated agents.

Is the CVE-2026-66012 reproduction verified?

Yes. Pruva reproduced CVE-2026-66012 with high confidence in a sandboxed environment, capturing the full agent transcript and artifacts as evidence.
11 · References

References for CVE-2026-66012

Authoritative sources for CVE-2026-66012 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.