SiYuan’s MCP Route Turned Anonymous Readers Into Workspace Administrators — CVE-2026-66012
A missing authorization gate on SiYuan’s Model Context Protocol endpoint exposed all 31 of the application’s MCP tools to low-privilege Reader identities. In the most dangerous supported deployment, SiYuan’s anonymous Publish service supplied that Reader token automatically, turning an unauthenticated request into workspace-wide read, write, delete, and administrative access.
CVE-2026-66012 was published on July 25 with a critical 10.0 score. The vendor advisory had already disclosed the chain on July 13, and SiYuan shipped the fix in version 3.7.2 on July 14. The CVE record marks versions before 3.7.2 affected; the vendor’s reproducer specifically targets 3.7.1. Operators should move to 3.7.2 or later rather than infer safety for an older branch from that narrower reproducer.
This is not an MCP protocol failure. It is a role-enforcement failure at an MCP trust boundary: the route checked whether a caller had a valid identity but did not check whether that identity was an administrator or was constrained to read-only actions.
One Reader token reached 31 administration-grade tools
SiYuan registered POST /mcp behind its general authentication middleware alone. After a request passed that check, the MCP dispatcher did not inspect the caller’s role before invoking a selected tool. That made tools for workspace files, SQL, templates, notebooks, plugins, and skill installation available to a Reader even though their effects were equivalent to administrative operations.
The file tool was the decisive primitive. Its path control blocked traversal outside the workspace, but sensitive configuration and executable extension directories live inside that boundary. A caller could read conf/conf.json, which the advisory says contains accessAuthCode, api.token, and cookieKey in plaintext; write or delete workspace data; and place files under data/plugins/.
The vendor advisory demonstrates the final transition as delayed code execution rather than immediate server-side command injection. A planted plugin is loaded the next time the desktop application opens the workspace. Because that Electron plugin context has Node integration enabled and context isolation disabled, its JavaScript can invoke operating-system functionality with the desktop user’s privileges.
Anonymous Publish converted missing authorization into no-auth takeover
The vulnerable MCP route still required a valid SiYuan token. The anonymous Publish configuration removed that obstacle. When an operator enabled Publish without password authentication, its reverse proxy attached a Reader-scoped JSON Web Token to proxied requests. An outside visitor could therefore reach /mcp without supplying credentials, while the kernel saw an authenticated Reader.
Password-protected Publish was not a complete defense. According to the vendor advisory, a legitimate Reader account could invoke the same administration-grade primitives. Anonymous mode made the flaw unauthenticated; the underlying defect was that Reader authority and MCP tool authority were never separated.
Exposure also depends on reachability. A SiYuan instance with Publish disabled and its management service restricted to a trusted local boundary does not present the same remote path. But local-only assumptions should be verified at the reverse proxy and firewall, not inferred from desktop use: a forwarded Publish port, container mapping, tunnel, or shared Reader account changes the threat model.
The patch adds three independent boundaries
SiYuan’s fix does more than add a single conditional. The MCP POST, GET, and DELETE routes now require an administrator role; mutating MCP operations also pass through the read-only check. The file tool explicitly refuses access to conf/conf.json. Finally, anonymous Publish requests are blocked from /mcp and a broader set of administration, configuration, import/export, plugin, synchronization, and sensitive file paths before a Reader token is attached.
That layered change is the right pattern. Endpoint authorization stops low-privilege principals, resource-level denial protects crown-jewel credentials if another route is misclassified, and the reverse proxy no longer manufactures an authenticated path to administration APIs. Any one boundary can fail without immediately recreating the full chain.
There is a documentation wrinkle worth noting during triage: the CVE record links commit c72ca4c, which is the tagged 3.7.1 commit and only changes README anchors. The authorization fix visible in the 3.7.2 comparison is commit df51c2b. Defenders validating backports should inspect the actual middleware, file-tool, and Publish-proxy changes rather than rely on the CVE record’s commit link alone.
Defensive engineering response
- Upgrade every SiYuan deployment to 3.7.2 or later. Version 3.7.3 is already available; do not leave an internet-reachable 3.7.1 instance in service while testing.
- Disable Publish until the upgrade is complete. If publishing is required, enforce authentication, restrict source networks, and block
/mcpplus administrative API families at the edge. A Publish password alone does not remove the pre-patch Reader escalation. - Rotate exposed kernel secrets. Treat
accessAuthCode, the API token, the cookie-signing key, and active sessions as compromised if a vulnerable Publish endpoint was reachable. Rotating only the Publish password is insufficient. - Review workspace integrity. Inspect
data/plugins/, skill and template directories, configuration changes, unexpected files, deleted content, and repository or history activity. A malicious plugin may remain dormant until a later desktop launch. - Hunt at both network and host layers. Look for MCP initialization and
tools/calltraffic on Publish ports, unusual full-file reads, writes beneath plugin directories, new child processes from SiYuan or Electron, and unexplained outbound connections after startup. - Apply the authorization lesson to other MCP servers. Authentication proves who called a tool; it does not establish that the caller may perform every action exposed by that server. Enforce role and resource policy before dispatch, then constrain each high-impact tool again.
CVE-2026-66012 shows why an MCP endpoint cannot inherit the lowest common privilege of the surrounding application. Tool descriptions that call an action “read-only” or “for debugging” are not controls. Once file mutation, credential access, plugin installation, and SQL share one authenticated dispatcher, every identity admitted to that dispatcher effectively receives the strongest primitive unless code enforces otherwise.
Sources: