iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
AI Security

AI 這麼聰明,為什麼還會被騙?30 天搞懂 AI 資安系列 第 6

Day 06 - OWASP LLM02:Sensitive Information Disclosure,秘密到底是怎麼被 AI 洩漏的?

  • 分享至 

  • xImage
  •  

hihi,我是歐娜😺

昨天講完 OWASP LLM01:Prompt Injection。

攻擊者想辦法影響模型的行為之後,很常出現的一個結果就是:

資料被拿走了。

所以今天來看 OWASP LLM Top 10 2026 的第二名:

LLM02:Sensitive Information Disclosure(敏感資訊洩漏)。

一開始看到這個名字,我覺得滿好理解的。

不就是:

不要讓 AI 把密碼、API Key、個資講出來?

但真的往裡面看之後才發現,不只是這樣🤣

因為敏感資料不一定是從 AI 最後「講出來」的。

它可能出現在:

  • Prompt
  • RAG 找回來的文件
  • Tool Output
  • Agent Memory
  • Log / Trace
  • Embedding
  • System Prompt

所以今天真正想看的不是:

怎麼叫 AI 不要講秘密?

而是:

為什麼這個秘密會進到 AI 能碰到的地方?

先搞清楚,什麼算 Sensitive Information?

最直覺的大概就是:

  • Password
  • API Key
  • Access Token
  • 身分證字號
  • 信用卡資訊
  • 醫療紀錄

但其實不只這些......

例如還有:

  • 公司內部文件
  • 客戶資料
  • 財務資訊
  • 尚未公開的產品資訊
  • 原始碼
  • 法律文件
  • 商業機密

都可能是 Sensitive Information!

而且有一個很重要的觀念:

敏感不是單純看「這份資料是不是秘密」,還要看「現在這個人有沒有權限看到」。

例如 HR 可以看員工薪資資料,但一般員工不行。

所以同一份資料,給不同的人看到,結果可能完全不同。

這件事到了 RAG 裡面就會變得非常重要!

RAG 找得到,不代表你有權限看

用跟前幾天一樣的假設,今天公司做了一個內部 AI Assistant。

架構大概是:

使用者
↓
提出問題
↓
Vector Search
↓
找到相關文件
↓
文件放進 LLM Context
↓
產生答案

現在 Knowledge Base 裡有兩份文件:

  • A.pdf:一般員工調薪制度
  • B.pdf:主管限定的年度薪資調整名單

使用者問:

公司今年的調薪制度是什麼?

Vector Search 會做什麼?

它主要是在找:

哪一段內容跟「調薪」這個問題最相似?

A.pdf 很相關。 B.pdf 也超級相關。

如果系統沒有做好權限控制,就可能變成:

使用者問題
↓
Vector Search
↓
A.pdf
B.pdf  (← 使用者其實沒有權限)
↓
全部塞進 LLM Context
↓
LLM 產生答案

這時候問題其實在 AI 回答之前就已經發生了。

因為 Vector Search 只負責幫你找:

「哪些資料跟使用者的問題最相關?」

它不一定會順便幫你判斷:

「這個使用者有沒有權限看這些資料?」

所以當使用者問:公司今年的調薪制度是什麼?

系統可能同時找到:

  • 一般員工都可以看的「調薪制度」。
  • 只有主管能看的「年度薪資調整名單」。

因為這兩份文件都跟「調薪」很相關。

但「很相關」不代表「有權限」。

所以 RAG 不能只做:

使用者問題
↓
找最相關的文件
↓
全部丟給 LLM

還要先確認:

使用者問題
↓
確認這個使用者能看哪些資料
↓
只從有權限的資料裡搜尋
↓
把結果交給 LLM

這就是為什麼在 RAG 裡:

Similarity Search 解決的是「找得到什麼」,Authorization 解決的是「你能不能看」。

這兩件事一定要分開處理。

就算某份文件跟問題的 Cosine Similarity 很高,也只代表它「很相關」,不代表這個使用者「有權限取得」!

Authorization 要發生在 Retrieval 之前

那可以先全部搜尋完,再把沒有權限的資料過濾掉嗎?

最好不要。

例如:

搜尋全部文件
↓
拿到 A.pdf + B.pdf
↓
丟進 LLM
↓
LLM 產生答案
↓
最後再過濾敏感資訊

這樣的問題是走到「丟進 LLM」這一步時,

B.pdf 已經進入 Context 了。

所以比較正確的方式應該是:

User
↓
確認 Identity
↓
確認 Role / Permission
↓
只搜尋有權限的資料
↓
Vector Search
↓
LLM

也就是:

Authorize before Retrieval。

例如概念上可能會像:

const documents = await vectorSearch({
  query,
  filter: {
    tenantId: user.tenantId,
    allowedRoles: {
      contains: user.role
    }
  }
})

先限制「這個人可以搜尋哪些資料」,再去做 Semantic Search。

而不是先把整間公司的文件拿給模型,再跟它說:

這些資料你可以看,但有些不能講出去喔~

這樣的作法怎樣想都會覺得怪怪的吧🤣

System Prompt 也不是保險箱

另外一個很容易出現的問題是:

把 Secret 直接寫進 Prompt。

例如:

You are our internal assistant.

Database Password: abc123
API_KEY: sk-xxxxx

Never reveal these values to the user.

這樣的 prompt 乍看之下好像有規則:

不准洩漏。

但問題是:

你已經先把秘密交給模型了。

只要它進入 Context,就代表後面可能受到 Prompt Injection、錯誤輸出、Debug 資訊或其他問題影響。

所以 API Key、Password、Access Token 這類 Secret,真正應該放的地方是:

  • Secret Manager
  • Environment Variable
  • Credential Store

真正需要呼叫 API 時,由 Application Backend 去使用。

例如:

LLM
↓
決定要呼叫 getCustomer()
↓
Backend
↓
從 Secret Manager 取得 Credential
↓
呼叫 API

而不是:

LLM:
「這是我們公司的 API Key,
你等等記得不要講出去喔。」

🤣🤣🤣🤣🤣🤣

一個我個人覺得比較好記的原則就是:

模型不需要知道的 Secret,就不要讓它進 Context。

洩漏不一定發生在最後的回答

還有一個我以前很容易忽略的地方:

Log。

假設今天為了方便 Debug,我把整個 AI Request 都記下來:

logger.info({
  prompt,
  retrievedDocuments,
  toolOutput,
  response
})

工程師看到可能會覺得:

超棒,之後出 Bug 很好查。

但如果 retrievedDocuments 裡面剛好包含:

  • 客戶姓名
  • 電話
  • 身分證字號
  • 內部合約
  • API Key

這些資料就全部被複製到 Logging System 裡了。

原本資料可能只有 AI Application 可以存取。

現在可能變成:

AI Application
↓
Logging Platform
↓
APM
↓
Debug Dashboard
↓
工程師帳號
↓
第三方 Observability Service

資料又多流過了好幾個地方。

所以 Sensitive Information Disclosure 不一定長這樣:

AI:「你的 API Key 是 sk-xxxxx。」

它也可能是:

AI 回答完全正常
↓
但是完整 Prompt 被寫進 Log
↓
Prompt 裡剛好有客戶個資
↓
Log 保存半年

使用者什麼都沒看到。

但資料一樣已經離開原本應該存在的範圍。

所以 OWASP 2026 在談 LLM02 時,也特別把:

  • Tool Arguments
  • Reasoning Trace
  • Retrieved Chunks
  • Logs
  • Telemetry

視為可能成為敏感資料洩漏的地方。

所以在檢查 Sensitive Information Disclosure 時,不能只看「AI 最後回了什麼」,還要看資料在整個 AI 系統裡經過了哪些地方、又被存到了哪裡。

Embedding 也不是加密

再來是 Vector Database 很容易出現的另一個誤會。

假設一段文字經過 Embedding:

員工今年薪資是 80,000 元
↓
Embedding Model
↓
[0.21, -0.84, 0.17, 0.62, ...]

看起來已經完全不是人類看得懂的文字了。

所以可能會直覺覺得:

都變成 Vector 了,應該安全了吧?

但不是。

Embedding 不是 Encryption。

Embedding 的目的是:

保留文字的語意特徵。

Encryption 的目的才是:

沒有 Key 的人不能還原資料。

這兩個完全不同。

目前已經有 Embedding Inversion 相關研究,可以從 Vector Representation 重建部分原始資訊。

所以:

Backup 裡面只有 Embedding,沒有原始文件。

不代表:

Backup 裡沒有敏感資料。

Vector Database 一樣需要:

  • Access Control
  • Tenant Isolation
  • Encryption
  • Backup Protection
  • Export Permission

不能因為裡面長得像:

[0.23, -0.91, 0.44 ...]

就把它當成沒有價值的資料。

那到底要怎麼防?

看到這裡會發現:

Sensitive Information Disclosure 不太可能靠 System Prompt 加一句:

不可以洩漏敏感資訊。

就解決。

真正要做的是從整條 Data Flow 開始看。

我自己會用這幾個問題檢查:

這份資料真的需要進 AI 嗎?
↓
這個使用者有權限取得嗎?
↓
模型真的需要看到全部欄位嗎?
↓
輸出前需不需要再做敏感資料偵測 (DLP)? 把不該出現的內容遮蔽 (Redaction)?
↓
Log / Trace 會不會又存了一份?

1. Data Minimization

假設 AI 只是要回答訂單狀態。

它可能只需要:

{
  "orderId": "A123",
  "status": "SHIPPED"
}

那就不要直接把完整 Customer Object 丟給它:

{
  "name": "Fiona",
  "phone": "09xxxxxxxx",
  "address": "...",
  "creditCard": "...",
  "orderId": "A123",
  "status": "SHIPPED"
}

模型用不到的東西,就不要給。

模型沒拿到的資料,就比較不可能從模型這一層洩漏。

2. Authorization before Retrieval

RAG 不應該只是:

Query
↓
Similarity Search
↓
LLM

而應該是:

User Identity
↓
Authorization
↓
Allowed Data Scope
↓
Similarity Search
↓
LLM

權限應該在資料被撈出來以前就先限制。

3. Secret 不進 Prompt

API Key、Password、Token 放在 Secret Manager 或 Backend。

需要使用時由程式拿,不要交給模型保管。

4. Output 做 Sensitive Data Detection

即使前面都做了,輸出前還是可以再做:

  • PII Detection
  • DLP (Data Loss Prevention)
  • Masking
  • Redaction

當作最後一道防線。

5. Log 也要 Redact

不要無腦把:

  • Prompt
  • Context
  • Tool Output
  • Response
  • Reasoning Trace

完整記進 Production Log。

真的需要記錄,也應該先做 Masking、Access Control 和 Retention Policy。

我覺得 LLM02 最重要的一句話

昨天 Prompt Injection 我最後記住的是:

不要期待模型永遠不會被騙。

今天的 Sensitive Information Disclosure,我會記:

不要期待模型幫你保守一個它根本不該知道的秘密。

  • AI 不需要知道 API Key,就不要把 API Key 放進 Context。
  • 員工不能看主管文件,就不要讓 Retriever 把主管文件撈回來。
  • Log 不需要完整 Prompt,就不要全部記。
  • 模型只需要兩個欄位,就不要丟二十個欄位給它。

因為每多流過一層,敏感資料就多一個可能洩漏的地方。

所以 LLM02 真正要保護的,不只是:

「AI 最後有沒有把秘密講出來?」

而是要從資料進入 AI 系統開始,一路去看:

它進了哪個 Context、被誰 Retrieval、經過哪些 Tool、留下哪些 Log,又被存到哪些地方。

這才是 Sensitive Information Disclosure 真正麻煩的地方。


上一篇
Day 05 - OWASP LLM01:Prompt Injection,不只是「忽略前面的指令」
下一篇
Day 07 - OWASP LLM03:Excessive Agency,Agent 不是越能幹越好
系列文
AI 這麼聰明,為什麼還會被騙?30 天搞懂 AI 資安9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言