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.
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).
CVE-2026-66012 Severity
CVE-2026-66012 is rated critical severity.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
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 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 Proof of Reproduction for CVE-2026-66012
- 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
Unauthenticated JSON-RPC POST /mcp tool calls through the Publish reverse proxy, including file writes for plugin.json, index.js, and petals.json
- 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
Root Cause and Exploit Chain for CVE-2026-66012
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
/mcpto read workspace files, exfiltrateconf/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/mcppath.
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
/mcpthrough the Publish reverse proxy on v3.7.1; unauthorized file write/read;conf/conf.jsonexfiltration; plugin files andpetals.jsonplanted using the same unauthenticated/mcpsession; real SiYuan Electron desktop launched under Xvfb; planted plugin executes attacker-controlled JavaScript with Node/Electronchild_processaccess and writes a marker containingidoutput. Fixed v3.7.2 and Publish-auth-enabled controls reject the initial unauthenticated/mcprequest 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
- Run
bundle/repro/reproduction_steps.sh. - 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 /mcpthrough the real Publish reverse proxy at127.0.0.1:6808. - The script obtains an unauthenticated MCP session, writes and reads
pwned.txt, exfiltratesconf/conf.json, plants a desktop plugin andpetals.jsonvia 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 containingidoutput tobundle/logs/repro/desktop-rce-marker.log. - 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/mcprequest 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— unauthenticatedPOST /mcp initializethrough the Publish reverse proxy returns HTTP 200 andMcp-Session-Idon v3.7.1.bundle/logs/repro/mcp-write-response.log— MCPfiletool writespwned.txtas an unauthenticated attacker.bundle/logs/repro/mcp-read-response.log— MCPfiletool reads back the attacker-controlled content.bundle/logs/repro/mcp-conf-response.log— MCPfiletool readsconf/conf.jsonfrom the workspace.bundle/logs/repro/mcp-plugin-json-write-response.log,bundle/logs/repro/mcp-plugin-index-write-response.log, andbundle/logs/repro/mcp-petals-write-response.log— plugin planting performed through the same unauthenticated MCP session.bundle/logs/repro/siyuan-desktop-rce.logandbundle/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, containingPRUVA_MCP_DESKTOP_RCEandidoutput.bundle/logs/repro/siyuan-vuln-auth.logandbundle/logs/repro/mcp-auth-control-response.log— Publish authentication enabled blocks unauthenticated/mcp.bundle/logs/repro/siyuan-fixed-anon.logandbundle/logs/repro/mcp-fixed-control-response.log— fixed v3.7.2 blocks the same unauthenticated/mcprequest 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
/mcpand 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
/mcpthrough 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
/tmpworkspaces 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
/mcpwrite 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.
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 -20Cloning into bare repository '/pruva/project-cache/repo-mirrors/siyuan.git'...
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.2Cloning into '/pruva/project-cache/repo'... done. c72ca4cd09019e5f64afdee8f8c6ec5ef34858db 726dae1d518927f70ea609bc146288b9aa95e366
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.2c72ca4cd 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.
How to Fix CVE-2026-66012
FAQ: CVE-2026-66012
Is CVE-2026-66012 exploitable?
How severe is CVE-2026-66012?
What type of vulnerability is CVE-2026-66012?
Which versions of siyuan are affected by CVE-2026-66012?
How can I reproduce CVE-2026-66012?
Is the CVE-2026-66012 reproduction verified?
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.