hihi,我是歐娜😺
昨天講 Sensitive Information Disclosure 時,有提到一個很重要的觀念:
模型不需要知道的資料,就不要給它。
今天的主題概念也很像,只是從「資料」換成了「能力」。
Agent 不需要做的事情,就不要讓它做!
今天來看 OWASP LLM Top 10 2026 第三名:
LLM03:Excessive Agency(過度代理權限)。
這一條在 2025 還排第六名,今年直接升到第三名。
原因其實不難理解。以前我們比較常擔心:
AI 會不會回答錯?
但現在 Agent 可以接 Tool、API、Database、Email、Cloud,甚至真的幫你執行操作。
問題就變成:
AI 如果判斷錯了,它到底有能力做出什麼?
Agency 可以先很簡單理解成:
AI 不只是回答你,而是有能力替你「做事情」。
普通 Chatbot 可能是:
User
↓
LLM
↓
回答文字
但 Agent 可能是:
User
↓
LLM
↓
判斷下一步要做什麼
↓
呼叫 Tool
↓
Email / Database / API / Cloud
例如你跟 Agent 說:
幫我整理今天的重要 Email。
它可能自己決定:
呼叫 getEmails()
↓
讀取信件
↓
分類內容
↓
整理摘要
這就是 Agency。
但如果今天這個 Agent 除了 getEmails(),還同時擁有:
sendEmail()
deleteEmail()
forwardEmail()
事情就開始不太一樣了......
因為它原本的工作明明只是:
整理 Email。
但你卻順便給了它:
寄信、轉寄、刪除 Email 的能力。
這就是 Excessive Agency 開始出現的地方。
這一點我覺得很重要!
看到 Agent 做了不該做的事情,我們很容易直覺想到:
又是 Prompt Injection?
但其實不一定。
Excessive Agency 關心的不是:
模型為什麼做錯判斷。
而是:
模型做錯判斷之後,為什麼有能力造成這麼大的影響?
例如:
Prompt Injection
↓
模型被騙
↓
刪掉 Database
也可能是:
Hallucination
↓
模型自己判斷錯
↓
刪掉 Database
甚至只是:
使用者講得不清楚
↓
模型理解錯
↓
刪掉 Database
前面的原因完全不同。
但後面有一個共同問題:
為什麼這個 Agent 有刪 Database 的能力?
所以 Prompt Injection 可以是「觸發點」,但 Excessive Agency 關心的是:
系統是不是給 Agent 太大的行動空間。
所以接下來真正要看的,不是模型「為什麼犯錯」,而是系統到底給了它多少能力。
OWASP 主要把這個問題拆成三個方向:
中文可以簡單理解成:
功能太多、權限太大、自主性太高。
看起來有點像,但其實是三件不同的事情。
假設今天做一個 Email Summary Agent。
需求只有:
幫使用者讀 Email,整理今天的重要信件。
它其實只需要:
readEmail()
但你接了一整套 Email Tool:
readEmail()
sendEmail()
deleteEmail()
forwardEmail()
createFilter()
這時候問題不是權限,而是:
你根本不該把這麼多 Function 提供給它。
Agent 被允許使用哪些 Tool,本身就是安全邊界的一部分。
所以不要因為:
「反正這個 API 都做好了,以後可能用得到。」
就全部丟給 Agent。
如果現在只需要讀:
✅ readEmail()
那就只給:
✅ readEmail()
而不是:
✅ readEmail()
✅ sendEmail()
✅ deleteEmail()
✅ forwardEmail()
這就是 Minimize Functionality。
但 Tool 數量不是唯一的問題。
就算 Agent 只拿到一個 Tool,如果這個 Tool 背後的權限太大,一樣會出事。
第二種很容易跟剛剛搞混。
假設我們已經很乖了。
Agent 只有一個:
queryDatabase()
看起來功能沒有很多。
但這個 Tool 連 Database 時,使用的 Service Account 居然有:
SELECT
INSERT
UPDATE
DELETE
那問題就來了。
Agent 明明只是要:
查詢商品資料。
實際上背後的 Identity 卻可以:
新增、修改、刪除資料。
這就是 Excessive Permissions。
功能可能只有一個,但背後使用的 Credential 權限太大。
例如原本是:
Agent
↓
queryProducts()
↓
Database Account
↓
SELECT / INSERT / UPDATE / DELETE
但比較合理的應該是:
Agent
↓
queryProducts()
↓
Read-only Database Account
↓
SELECT
這就是我們在傳統 Cloud Security 裡很熟悉的:
Least Privilege(最小權限原則)。
只給完成這個工作真正需要的權限。
所以到這裡可以看到,「可以用哪些 Tool」跟「Tool 背後能做到什麼」其實是兩個不同層次。
這兩個我一開始也很容易混🤣
可以直接這樣記:
Agent 可以叫哪些 Tool?
例如:
readEmail()
sendEmail()
deleteEmail()
這個 Tool 到後面的系統,到底有多大的權限?
例如:
Database Credential:
SELECT / UPDATE / DELETE
所以可能出現:
Tool 很少
但 Tool 背後權限超大
也可能是:
Tool 很多
但每個 Tool 權限都很小
這兩種都要看!!
而前面兩個都在管「Agent 能做什麼」。
但還有最後一個問題:就算它有這個能力,要不要讓它自己決定什麼時候做?
第三個是我覺得 Agent 特別需要注意的:
Autonomy(自主性)。
假設 Agent 可以寄 Email。
不代表每一次寄信都應該讓它自己直接送出去。
例如:
User:
幫我處理今天所有客戶抱怨。
Agent 判斷:
這個客戶很不爽
↓
我幫他退款
↓
我寄一封道歉信
↓
退款完成
效率超高。
但使用者原本可能只想要:
幫我整理有哪些客戶需要處理。
結果 Agent 自己決定「處理」等於自動做了:
退款 + 寄信
這就是 Autonomy 的問題。
對一些高風險操作,流程不應該是:
LLM 決定
↓
直接執行
而是:
LLM 建議動作
↓
系統判斷這是高風險操作
↓
Human Approval
↓
真的執行
例如:
這些操作通常都值得多一道確認。
前幾天提過的 Human-in-the-loop,到了 Excessive Agency 這裡,就是限制 Autonomy 很重要的一道手段。
也就是不要讓模型一做完判斷,就立刻真的執行,而是在高風險操作前,再交給人確認一次。
到這裡可能會想到一個很直覺的做法:
那我直接在 System Prompt 裡規定「不能亂刪」不就好了?
假設我們在 System Prompt 裡寫:
You must never delete production data
without explicit user permission.
有用嗎?
有。
但不能把它當成真正的安全控制。
因為這個限制最後還是在靠:
模型自己遵守。
真正的安全邊界應該放在模型外面。
例如:
if (action === "deleteUser") {
if (!userApproved) {
throw new Error("User approval required")
}
}
甚至後端 API 自己再確認:
而不是 LLM 說:
我覺得可以刪。
Backend 就回答:
好的 😍
🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣
OWASP 在這裡有一個很重要的概念叫:
Complete Mediation。
簡單講就是:
每一次真正要執行操作時,都重新檢查權限。
不要因為前面 Agent 已經通過一次驗證,就假設後面所有 Tool Call 都一定合法。
但光是「每次都檢查權限」還不夠,下一個問題是:到底要用誰的權限執行?
還有一種很危險的設計:
所有 Agent 都共用同一個高權限 Service Account。
例如:
Amy
Kevin
Admin
Intern
↓
AI Agent
↓
同一個 Super Admin Service Account
↓
Google Drive
這樣會發生什麼?
Intern 明明只能看自己的文件。
但是 Agent 背後使用的 Identity 可以看全公司的 Drive。
如果權限判斷全部交給 LLM:
「記得不要把別人的文件給 Intern 喔。」
這個安全設計就比較危險🤣
比較好的概念是:
User
↓
OAuth / Identity
↓
Agent
↓
使用該 User 的 Permission Scope
↓
Downstream System
也就是:
Agent 幫誰做事情,就盡量只帶著那個人原本擁有的權限去做。
不要因為中間多了一個 AI,就把原本的 IAM 全部繞掉。
權限範圍控制好了,還有另一個容易被忽略的地方:Tool 本身設計得有多自由。
另外一種我覺得也很值得注意的是:
executeShell(command)
這種 Tool。
假設你的需求只是:
幫我列出
/reports裡面的檔案。
你可以給它:
listReports()
或者直接給:
executeShell(command)
兩個都做得到。
但第二個代表 Agent 理論上可能執行:
ls
rm
curl
chmod
cat
甚至更多東西。
這就是為什麼 Tool 設計最好越具體越好。
與其:
executeShell(command)
不如:
listReportFiles()
與其:
databaseQuery(sql)
不如:
getOrderStatus(orderId)
Tool 越 Open-ended,模型可以組合出來的行為就越難控制。
所以 Excessive Agency 不只是「權限太大」而已,而是要一起看:Tool 有多少、權限有多大、模型能不能自己決定,以及 Tool 本身有多自由。
整理一下,其實核心沒有很複雜。
需要 readEmail()
就不要順便給 deleteEmail()
這是在限制:
Functionality。
只需要查資料
就用 Read-only Credential
這是在限制:
Permission。
像是:
等等操作要加入 Human Approval。
這是在限制:
Autonomy。
不要讓 LLM 自己判斷:
我有沒有權限做這件事?
真正執行操作的系統還是要做:
假設真的不小心出錯了,但有兩種場景:
這兩種就完全不同等級🤣
所以 Tool Call 也應該有:
即使不能完全阻止錯誤,也可以限制爆炸範圍。
Day 05 的 Prompt Injection,我記的是:
不要期待模型永遠不會被騙。
Day 06 Sensitive Information Disclosure 是:
不要期待模型替你保守一個它根本不該知道的秘密。
今天的 Excessive Agency,我會記:
不要因為 Agent「可能做得到」,就讓它「什麼都做得到」。
因為模型會判斷錯。也可能被 Prompt Injection。甚至使用者自己都可能講得不夠清楚。
這些事情很難保證 100% 不發生。
但我們可以控制的是:
它有哪些 Tool?
↓
每個 Tool 有多少 Permission?
↓
哪些事情可以自己做?
↓
哪些事情一定要人類確認?
真正的 Agent Security,不是期待 AI 永遠做出正確決策。
而是:
就算它今天做錯決策,也不要讓它有能力把整個系統一起弄壞。