部落格 發布於 AIA: 2026年4月17日

McKinsey Lilli 平台被攻破:SQL Injection 打到 AI 的 prompt 層

這條攻擊鏈的起點,其實是很老派的 Web 弱點。Lilli 有 22 個 API 端點沒做驗證,其中一個還會把 JSON 請求裡的 key 直接串進 SQL。CodeWall 的自主 agent 就靠這條路,在兩小時內讀寫到 Lilli 背後整個資料庫:4,650 萬筆對話、72.8 萬份檔案、368 萬筆 RAG chunk、vector store metadata,還有操控 4.3 萬名使用者 AI 行為的系統提示詞(system prompt)。

真正的重點不是「又一個 SQL injection」,而是這個 SQL injection 已經直接打到 AI 平台最核心的資產層。對防禦方來說,提示詞、RAG chunk、vector store 這些東西都必須用和程式碼、secrets 同等強度的手段來保護。

SQL InjectionData ExfiltrationData GovernanceEnterprise AIAgentic AI
5 項對應的 AIDEFEND 防禦手法
來源: How We Hacked McKinsey's AI Platform 
作者: Paul Price (CodeWall)
原文發布: 2026年3月9日

威脅分析

  • 第 1 步:先從沒驗證的 API 端點找入口。 Lilli 有 22 個 API 端點沒做驗證,這代表攻擊者連帳號都還不用有,就能先對外露的介面一路試下去。CodeWall 的自主 agent 也是先從這個面開始探查。
  • 第 2 步:其中一個端點,會把 JSON key 直接拿去組 SQL。 這個設計錯誤讓 agent 能把 SQL injection 和 IDOR(橫向越權,換個 ID 就能讀到別人的資料)串起來,兩小時內就讀到正式環境背後的整個資料庫。
  • 第 3 步:更麻煩的是,這個資料庫裡放的不只是一般業務資料。 裡面同時有 4,650 萬筆對話、72.8 萬份檔案、368 萬筆 RAG chunk、vector store metadata、AI 助理設定,以及 95 份系統提示詞。也就是說,一旦資料庫被打穿,受影響的不是單一表格,而是整個 AI 平台怎麼回答、怎麼擷取、怎麼跟資料互動的那一層。
  • 第 4 步:同一個漏洞還能把 AI 行為直接改掉。 這個 SQL injection 不只可讀,還允許 UPDATE。攻擊者可以用一個 HTTP 呼叫就改掉系統提示詞、竄改 RAG 內容、移除 guardrail,或植入資料外洩指令,而且不需要重部署,也不需要改應用程式程式碼。
  • 為什麼這件事特別值得記住: Lilli 這樣跑了兩年,有 4.3 萬名使用者、每月 50 萬筆提示詞。人工掃描沒抓到;自主 agent 幾小時就找到。McKinsey 在 2026-03-01 收到通報後,2026-03-02 就完成修補並關閉未驗證端點,處置算快,但這個案例已經很清楚地告訴我們:只要傳統 Web 漏洞能打到提示詞和擷取層,整個 AI 平台就會一起失守。

適用的 5 項 AIDEFEND 防禦手法

AID-H-022.002
Runtime Integrity Enforcement (Signed Configurations)
極高
提示詞存在明文資料庫裡,這正是 CodeWall 利用的攻擊面。Signed-configuration 執行 - - 系統提示詞帶密碼學簽章、載入時驗證簽章 - - 能擋下「一個 UPDATE 就偷偷改掉」的情境。就算資料庫被攻破,被動過的提示詞通不過簽章驗證,就沒辦法進到模型裡。
AID-H-021.001
Chunk-Level Integrity Signing
極高
除了 368 萬筆 RAG chunk(包括 S3 路徑)都被曝光之外,這次的攻擊還因為同一個 SQL 注入漏洞允許 UPDATE,導致這些 chunk 能被竄改。Chunk-level 簽章代表每次擷取 chunk 時都要驗證簽章,被動過的 chunk 會在進模型前就被擋下。沒有這一層,任何讀寫資料庫的 bug 都會變成 RAG 投毒管道。
AID-D-004.005
Runtime Prompt Integrity Verification
極高
這次的失效點就在這裡:模型直接從資料庫載入系統提示詞,完全沒檢查它跟上次核准過的版本是否一致。對核准過的提示詞做雜湊和簽章、每次請求都驗一次,就算資料庫的稽核紀錄失效,只要提示詞被動過手腳,在送進推論(inference)前就會被擋下來。
AID-H-019.001
Tool Parameter Constraint & Schema Validation
這條 SQL injection 路徑,是從攻擊者可控制的 JSON key 被拿去組查詢結構開始。API 與工具參數應該有嚴格的結構定義,在進入 SQL 組裝前就拒絕非預期的 key、型別和資料表選擇器;尤其是能碰到提示詞、RAG chunk、檔案或聊天紀錄的端點。
AID-H-030.002
Lifecycle-Stage Authorization Gate
架構上的根本問題是:對話紀錄、RAG chunk、系統提示詞、使用者帳號、vector store metadata 全都擠在同一個可查詢的資料庫裡。依 AI 生命週期階段對每個資產類別設授權關卡 - - 不同憑證、不同存取路徑 - - 就能把一個 SQLi 的影響限縮在單一類別,而不是一次全部淪陷。

身為資安防禦者,我們應該這麼做

  • 盤點 AI 平台上儲存提示詞、RAG chunk、vector store metadata、agent 設定的所有位置。把它們移到帶完整性簽章的儲存層,並在載入或擷取時驗證簽章。
  • 我們要預先假設,單一個 SQLi 或 IDOR 就能影響到提示詞表。對提示詞、設定、RAG 表加上資料庫層稽核紀錄和即時警示 - - 任何部署 pipeline 以外的 UPDATE,都視為資安事件。
  • 對 AI 平台上每個 API 端點做一次 default-deny 稽核。Lilli 200 多個端點裡有 22 個沒驗證;你自己的環境裡大概也有類似的空窗。
  • 把 AI 資產儲存按類別分開(提示詞 / RAG / 對話紀錄 / 身分 / vector metadata)放到不同 store、用不同憑證;一個 bug 就沒辦法一次打穿所有層。
  • 把自主紅隊評估當成常規控制。人工掃描兩年漏掉這件事,機器速度的持續檢測是必要的補強。

2 個額外的防禦考量

AI 資產類別之間的爆炸半徑隔離

除了上面對應的技術,跑大型 AI 平台的團隊還應該考慮對各個儲存層做實體或邏輯隔離 - - 提示詞放一個 store、RAG chunk 放另一個、對話紀錄放第三個 - - 這樣單一資料庫被攻破,才不會像這次一樣直接變成整個 AI 平台全面淪陷。
建議做法: 把 AI 資產儲存按類別分開(提示詞 / RAG / 對話紀錄 / 使用者身分 / vector metadata)放到不同的資料庫或 schema,用不同的憑證和網路路徑管;要橫向移動就得突破好幾道獨立的防線,不是一次 SQLi 吃掉全部。

自主攻擊測試納入常規控制

CodeWall 的自主 agent 兩小時就串出整條攻擊鏈,人工掃描兩年都沒抓到。跑 AI 平台的防禦方可以再加一層:用機器速度持續做紅隊評估,測驗證覆蓋率、SQLi、還有 AI 資產層的竄改路徑,每次 release 都跑一次。
建議做法: 把自主測試 agent 接進上線關卡和正式環境的偏移檢查 - - 不是要取代傳統 AppSec,而是當成第二層防護,跟上平台新增端點和 AI 資產的速度。

結論

McKinsey Lilli 這案最值得記住的地方,是一個傳統 Web 漏洞一旦打到提示詞和擷取資料層,後果就不再只是資料庫被看光,而是整個 AI 行為層都能被改寫。AIDEFEND  的提示詞完整性、RAG chunk 簽章、分階段授權這幾條,剛好對應這種失守方式;營運上的重點則是把提示詞、RAG chunk、vector metadata 當成需要獨立完整性控制的核心資產,而不是把它們當成普通資料列,覺得只要放在資料庫裡就安全。