CVE-2026-101091 Overview
CVE-2026-101091 is a SQL injection vulnerability [CWE-89] in SiYuan, a personal knowledge management application, affecting all versions before v3.8.4. The flaw resides in the block query embed feature, which fails to validate that SQL statements executed against siyuan.db are read-only. Attackers craft malicious .sy documents containing non-read-only SQL statements that execute automatically during background indexing, rendering, or export operations. No authentication is required, and the previous check based on searching for the select substring could be bypassed using comments or subqueries.
Critical Impact
Unauthenticated attackers can execute arbitrary SQL statements against the SiYuan database by tricking a user into opening or importing a crafted .sy document, enabling data tampering and integrity loss.
Affected Products
- SiYuan versions before v3.8.4
- The kernel/model/index.go block indexing path
- The kernel/sql/block_query.go raw block query execution path
Discovery Timeline
- 2026-09-28 - CVE-2026-101091 published to NVD
- 2026-09-29 - Last updated in NVD database
Technical Details for CVE-2026-101091
Vulnerability Analysis
SiYuan supports embed blocks whose contents are populated by executing a SQL query against the local siyuan.db database. Before v3.8.4, the kernel validated these queries by checking whether the lowercased statement contained the substring select. This weak filter is trivially bypassed. An attacker can prefix a destructive statement with an SQL comment that contains select, or wrap it in a subquery, and the check will pass.
Because embed block scripts originate from document content, they are untrusted input. The vulnerable statements execute automatically during background indexing, note rendering, and export flows, so no user interaction with the embed block itself is required beyond opening a crafted .sy file. The result is unauthenticated SQL execution against the local database.
Root Cause
The root cause is improper neutralization of special elements used in an SQL command [CWE-89]. The pre-patch guard performed a substring match for select rather than parsing the statement and enforcing a single, read-only query. Multiple call sites that forwarded raw SQL to db.Query did not share a common validator, so any path missing the check became an injection sink.
Attack Vector
An attacker distributes a malicious .sy document (for example, via a shared workspace, template, or import) containing embed blocks with crafted SQL. When the victim opens, indexes, renders, or exports the document, SiYuan executes the attacker-controlled statement against siyuan.db under the local user's context. Exploitation requires network-delivered content and user interaction to open the document.
// Patch: kernel/model/index.go — replace substring check with strict validator
- if !strings.Contains(strings.ToLower(stmt), "select") {
+ // Embed block scripts come from document content and are untrusted:
+ // must be validated as a single read-only query. A "contains select"
+ // check can be bypassed by comments or subqueries.
+ if err := sql.CheckReadonlyBlockQueryStatement(stmt, embedBlock.Box); nil != err {
+ logging.LogWarnf("skip non-readonly embed block [%s] script: %s", embedBlock.ID, err)
continue
}
Source: SiYuan commit e8ace0c
// Patch: kernel/sql/block_query.go — central guard on every raw SQL exit
+func checkRawBlockQueryStmt(stmt, boxID string) bool {
+ if err := CheckReadonlyBlockQueryStatement(stmt, boxID); nil != err {
+ trimmed := strings.TrimSpace(stmt)
+ if "" != trimmed && !strings.HasPrefix(trimmed, "//!js") {
+ logging.LogWarnf("sql query [%s] rejected as non-readonly: %s", stmt, err)
+ }
+ return false
+ }
+ return true
+}
func SelectBlocksRawStmtArgs(stmt string, args []any, limit int) (ret []*Block) {
+ if !checkRawBlockQueryStmt(stmt, "") {
+ return
+ }
rows, err := query(stmt, args...)
Source: SiYuan commit e8ace0c
Detection Methods for CVE-2026-101091
Indicators of Compromise
- SiYuan kernel log entries containing skip non-readonly embed block or rejected as non-readonly, indicating rejected malicious embed queries after patching.
- Unexpected modifications to siyuan.db such as new, altered, or deleted rows in block tables outside of normal editing activity.
- .sy documents originating from external sources containing embed blocks whose SQL includes keywords like UPDATE, DELETE, INSERT, ATTACH, or PRAGMA.
Detection Strategies
- Statically scan imported .sy files for embed block SQL statements that are not single read-only queries.
- Monitor SiYuan process behavior for unexpected writes to siyuan.db outside interactive editing sessions.
- Review kernel warning logs after opening or importing untrusted notebooks to identify rejected statements.
Monitoring Recommendations
- Track SiYuan installations by version and alert on any host running a release earlier than v3.8.4.
- Audit workspaces that ingest shared or third-party notebook templates and log the source of every imported .sy file.
- Baseline siyuan.db file size and last-modified timestamps to flag anomalous change patterns.
How to Mitigate CVE-2026-101091
Immediate Actions Required
- Upgrade all SiYuan instances to v3.8.4 or later, which enforces read-only validation on every block query execution path.
- Do not open or import .sy documents from untrusted sources until the upgrade is applied.
- Back up existing siyuan.db databases before applying updates so integrity can be verified against a known-good state.
Patch Information
The fix is delivered in SiYuan v3.8.4 via commit e8ace0c89182c7ee1a1298ff2a849bb6a83dfdec. It introduces CheckReadonlyBlockQueryStatement and a shared checkRawBlockQueryStmt guard invoked by every code path that forwards raw SQL to db.Query, replacing the bypassable strings.Contains(..., "select") check. See the GitHub Security Advisory GHSA-67p9-hm94-xwf3 and the VulnCheck advisory for full details.
Workarounds
- Restrict .sy document imports to trusted authors and remove embed blocks from any externally sourced notebooks before opening them.
- Run SiYuan under a least-privileged user account with the database stored on a filesystem that supports snapshot-based rollback.
- Disable or avoid triggering export and re-indexing operations on notebooks of unknown provenance until upgrading.
# Verify installed SiYuan version and upgrade path
siyuan --version
# Expected output should be v3.8.4 or later
# Linux example: replace an older AppImage with the patched release
chmod +x SiYuan-linux-3.8.4.AppImage
mv SiYuan-linux-3.8.4.AppImage /opt/siyuan/SiYuan.AppImage
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

