Skip to content

v1.47.1 — 唯讀保證涵蓋所有執行路徑(安全性修復)

Choose a tag to compare

@CarlLee1983 CarlLee1983 released this 05 Aug 07:49
· 595 commits to main since this release
2ee730b

安全性修復 — 建議所有把資料庫交給 AI agent 操作的使用者升級

修復六個「看起來是讀、實際會寫」的權限繞過。它們都能在設定為 permission: query-only 的連線上寫入資料。

  • MongoDB $out / $merge 未被擋下(query、q、export)——$out 可覆寫任意 collection,--dry-run 還會把它預覽成安全操作。
  • PostgreSQL 多語句堆疊 —— SELECT 1 LIMIT 1; DELETE FROM users 以 SELECT 的身分通過 query-only。
  • snippet 的偽唯讀語句 —— 可寫 CTE 與 SELECT … INTO 能通過「開頭是 SELECT/WITH」的檢查。
  • snippet frontmatter 的 verify.query 未經驗證 —— 過去由 q <name> --verify 原封執行。
  • 唯讀證明只接在多連線 fan-out 上 —— 單連線 dbcli query "WITH gone AS (DELETE FROM users RETURNING *) SELECT * FROM gone" 直接刪表,不需要任何特殊語法,auto-limit 對 CTE 無效。
  • PostgreSQL 識別字中的 $ 被誤判為 dollar-quote 起點 —— a$q$ 是一個識別字,剖析器卻讀成字串起點,中間整段對所有安全檢查隱形。

利用這些繞過需要能下達指令的一方送出 payload,也就是 agent 本身 —— 而 dbcli 的威脅模型前提正是 agent 不完全可信,因此這些屬於權限繞過。

⚠️ 破壞性行為變更

開頭讀取但夾帶寫入的語句一律需要 admin:可寫 CTE、SELECT … INTO、EXPLAIN ANALYZE <寫入>、DESCRIBE ANALYZE <寫入>。

升級後需要改用 admin 的三類用法:data-admin 連線上的可寫 CTE;對寫入語句做 EXPLAIN ANALYZE / DESCRIBE ANALYZE(它會真的執行該語句);MySQL/MariaDB 的 SELECT … INTO @variable —— 最後一項其實是純讀取,屬於刻意保留的誤擋,因為為它加例外正是本次反覆產生新繞過的來源。

此外,admin 以下的權限等級拒絕多語句 SQL,且 snippet 一律拒絕寫入關鍵字(不看 permission 等級,admin 連線亦然)。

新增的結構性防護

執行路徑契約測試:src/adapters/ 以外每一處 <x>Adapter.execute(...) 都必須登記它倚賴的 gate,未登記的新路徑會讓測試失敗。六個洞裡有兩個正是靠列舉全部路徑才發現的 —— 逐一稽核指令找不到它們。


完整說明見 CHANGELOG;決策記錄見 docs/adr/0004-database-access-stays-a-cli-surface.md。