部落格 發布於 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 同等強度的手段來保護。

Agentic AIPrompt IntegrityData ExfiltrationEnterprise 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 當成需要獨立完整性控制的核心資產,而不是把它們當成普通資料列,覺得只要放在資料庫裡就安全。