CVE-2026-87809
Executive Summary
CVE-2026-87809 is an authorization bypass vulnerability affecting Siyuan prior to version 3.8.2. The flaw stems from a failure to apply publish-access filtering to embedded blocks before rendering content via the /api/export/preview and /api/lute/copyStdMarkdown API endpoints. Authenticated attackers with low-privilege reader access can exploit this vulnerability to extract rendered content from private, hidden, or publish-disabled blocks by querying public documents that contain embedded block references. The vulnerability carries a CVSS v3.1 score of 6.5 (Medium severity) due to high impact on confidentiality without requiring administrative privileges or user interaction.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Siyuan utilizes a block-based document model where content units (paragraphs, lists, code blocks, tables) possess distinct identifiers and granular privacy settings, such as publish-disabled, hidden, or private status. Document publishing mechanisms allow users to expose specific root documents publicly while withholding restricted or sensitive sub-blocks.
The vulnerability resides in the content rendering pipeline exposed by two specific backend endpoints:
/api/export/preview/api/lute/copyStdMarkdown
When a client issues a request to preview an export or request formatted Markdown output via these endpoints, the application invokes the Lute engine (Siyuan's Markdown parser and renderer) to parse and generate the output structure. If the targeted document contains embed queries or embedded block references targeting other blocks, Lute resolves and renders the target content.
The security failure occurs during the recursive resolution of embedded blocks. While the parent/container document passes initial publish-access authorization checks (as it is marked public or accessible to readers), the application omits secondary publish-access filtering on the child blocks embedded within it. As a result, the parser evaluates and renders embedded block contents regardless of whether those individual blocks are marked as private, hidden, or publish-disabled.
This vulnerability classifies as CWE-639 (Authorization Bypass Through User-Controlled Key). The backend trusts the context of the public parent document and fails to enforce Object-Level Access Control (OLA) on referenced sub-resources during parsing and export generation, creating an indirect data disclosure vector.
Exploitation Scenarios
No public Proof-of-Concept (PoC) code is currently available; the attack chain detailed below is inferred directly from the vulnerability class and official metadata.
- Reconnaissance & Target Identification: An attacker obtains low-privilege reader access to a Siyuan instance or accesses a publicly accessible document published by the target instance. The attacker identifies or creates a document containing embed queries that reference block IDs across the workspace.
- Flaw Triggering: The attacker issues an HTTP request to either the
/api/export/previewor/api/lute/copyStdMarkdownendpoint, supplying a target document context that includes embedded references to private or publish-disabled blocks. - Execution Method: Because the backend processing logic fails to apply publish-access filters during rendering, the Lute engine executes the block queries, extracts the target block data from the database, and renders the full text output inside the response stream.
- Post-Exploitation Impact: The attacker reads the HTTP response body containing the rendered content of the private or hidden blocks. This allows for unauthorized retrieval of sensitive enterprise notes, internal documentation, API keys, or credentials stored in restricted blocks across the Siyuan database.
Impact Assessment
CVSS Score & Vector Analysis
- CVSS v3.1 Base Score: 6.5
- Vector String:
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Attack Vector (AV:N): Exploit is remotely accessible over the network.
- Attack Complexity (AC:L): No complex conditions or race states are required.
- Privileges Required (PR:L): Requires basic reader permissions on the target document/workspace.
- User Interaction (UI:N): Requires no interaction from victim users.
- Scope (S:U): The vulnerability does not cross authorization boundaries to impact underlying hosting infrastructure beyond the Siyuan application context.
- Confidentiality (C:H): Complete access to private, hidden, or publish-disabled block contents accessible via embed queries.
- Integrity (I:N): No ability to modify or corrupt application data.
- Availability (A:N): No direct denial-of-service capability inherent to the authorization bypass.
Business & Operational Risks
- Data Exfiltration: Unauthorized disclosure of restricted knowledge base content, business logic, intellectual property, or confidential user notes.
- Credential Exposure: Accidental inclusion of sensitive keys or operational tokens in private blocks can lead to secondary compromises if read by unauthorized entities.
- Compliance Violations: May breach data protection standards (e.g., GDPR, HIPAA) if sensitive personal information stored in private blocks is leaked via public documents.
Detection Guidance
Sigma Rule
title: Siyuan Unauthorized Embedded Block Access Attempt
id: 5e6a71cb-8f1b-4d6d-b8d1-72a39d883b10
status: experimental
description: Detects HTTP requests to Siyuan export preview and Markdown copy endpoints which may be abused to bypass publish-access filtering on embedded blocks (CVE-2026-87809).
author: ValtersIT Security
date: 2026-03-30
logsource:
category: webserver
product: nginx
detection:
selection_endpoints:
c-uri|contains:
- '/api/export/preview'
- '/api/lute/copyStdMarkdown'
selection_methods:
c-method: 'POST'
condition: selection_endpoints and selection_methods
falsepositives:
- Legitimate administrative users exporting documents or requesting Markdown previews.
level: medium
tags:
- attack.initial_access
- attack.t1213
- cve.2026.87809
YARA Rule
rule Siyuan_CVE_2026_87809_API_Access {
meta:
description = "Detects HTTP request patterns targeting Siyuan endpoints vulnerable to CWE-639 block access bypass"
author = "ValtersIT Threat Intelligence"
date = "2026-03-30"
cve = "CVE-2026-87809"
severity = "Medium"
strings:
$ep1 = "/api/export/preview" ascii wide
$ep2 = "/api/lute/copyStdMarkdown" ascii wide
$http_post = "POST " ascii wide
condition:
$http_post and (1 of ($ep*))
}
Suricata IDS Rule
alert http $EXTERNAL_NET any -> $HOME_NET $HTTP_PORTS ( \
msg:"SEC-VULN - Siyuan Potential Embedded Block Authorization Bypass Attempt (CVE-2026-87809)"; \
flow:established,to_server; \
http.method; content:"POST"; \
http.uri; pcre:"^\/api\/(export\/preview|lute\/copyStdMarkdown)"; \
classtype:web-application-attack; \
sid:80000101; \
rev:1; \
metadata:cve CVE-2026-87809, created_at 2026_03_30; \
)
Elastic Detection
sequence by host.id, user.id with maxspan=5m
[network where event.type == "start" and
http.request.method == "POST" and
http.request.uri : ("/api/export/preview*", "/api/lute/copyStdMarkdown*")]
Splunk SPL Query
index=web_proxy OR index=sourcetype_nginx_access uri_path IN ("/api/export/preview", "/api/lute/copyStdMarkdown") http_method=POST
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, user, uri_path, http_method, status
| where count > 5
| convert timeformat="%Y-%m-%d %H:%M:%S" ctime(first_seen) ctime(last_seen)
| table first_seen, last_seen, src_ip, user, uri_path, count, status
Wazuh OSSEC Rule
<group name="web,siyuan,cve-2026-87809,">
<rule id="100810" level="7">
<if_sid">31100</if_sid>
<url>/api/export/preview|/api/lute/copyStdMarkdown</url>
<description>Siyuan potential publish-access bypass attempt via export/markdown rendering (CVE-2026-87809)</description>
<mitre>
<id>T1213</id>
</mitre>
<group>web_attack,access_control_bypass</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch Status
Patch Confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source)
Note: While description references versions prior to v3.8.2, formal patch confirmation and verified vendor distribution tracks remain unverified across primary threat intelligence feeds.
1. Immediate Mitigations
- URL/Endpoint Restricted Access: Configure reverse proxies (e.g., Nginx, HAProxy) or Web Application Firewalls (WAF) to block external access to
/api/export/previewand/api/lute/copyStdMarkdownfor unauthenticated or non-administrative user sessions. - Document Audit: Review publicly accessible documents to remove embedded block queries (
((block_id))or SQL embed blocks) referencing non-public workspace sections. - Privilege Reduction: Limit broad reader privileges across instances holding sensitive information until vendor fixes can be fully verified.
2. Patch & Upgrade Steps
- Monitor official Siyuan repository releases and secure patch channels for confirmed deployment binaries of version 3.8.2 or later.
- Upon availability, update Siyuan deployment instances in staging environments, validating that block-level permissions are strictly enforced when issuing requests to
/api/export/previewand/api/lute/copyStdMarkdown.
3. Long-Term Hardening
- Instance Segmentation: Maintain strict network separation between internal-only knowledge bases and public-facing Siyuan instances.
- Zero-Trust Access: Enforce strict identity verification and role-based access control (RBAC) at the network layer prior to routing requests to internal API services.
References
- National Vulnerability Database (NVD) - CVE-2026-87809 Detail: https://nvd.nist.gov/vuln/detail/CVE-2026-87809
- CWE-639: Authorization Bypass Through User-Controlled Key: https://cwe.mitre.org/data/definitions/639.html
- Siyuan Official Repository & Technical Documentation: https://github.com/siyuan-note/siyuan
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.