上一篇講模型輸出後可能造成的影響,模型輸出如果直接被塞進 HTML、SQL 或 Shell,最後可能變成 XSS、SQL injection 或 Command Injection,這篇來看看系統到底允許模型替使用者做什麼?
2026 年 4 月,車輛租賃 SaaS 公司 PocketOS 的正式環境資料庫,在九秒內被刪光,做這件事情的是 Cursor 的 coding agent,它原本只是在處理 staging 環境的例行工作,碰到憑證不符之後,沒有停下來問人,而是自己跑去另一個不相關的檔案裡翻出一組 Railway API token,接著直接呼叫 API 刪除 volume,那組 token 原本只是拿來管理自訂網域,但權限卻大到可以操作整個 Railway API,才釀成這起事件(The Register)。
這個案例值得注意的地方是整個系統設計允許這件事發生,API token 是 agent 自己在專案裡找到的,而且那組 token 握有超過原本用途的權限,而且在真正執行刪除之前,並沒有任何一道獨立於模型之外的關卡。
所以在設計會呼叫工具的 AI 系統時,要確認是不是只賦予任務需要的權限:
這些問題指向 OWASP 的 LLM03:2026 Excessive Agency,這個風險講的是應用程式交給模型的功能太多、權限太大,或者在高風險操作上讓它自己決定,這一項在 2026 版從 2025 版的第 6 名升到第 3 名,也反映出一個趨勢:越來越多工作開始交給 AI 直接執行,出事的地方不再只是聊天視窗,而是那些會自己呼叫工具、存取系統,甚至直接改變狀態的 agent 部署,OWASP 在這一條裡也直接對應到 Agentic Top 10 的 ASI02 工具濫用(Tool Misuse)、ASI03 身分與權限濫用(Identity & Privilege Abuse)與 ASI08 連鎖失效(Cascading Failures)。
操作聊天視窗時,很容易讓人以為是模型親自去查了資料庫、寄了信、改了檔案,實際上模型只負責決定要呼叫哪個工具以及要帶哪些參數,真正執行動作的是後面的應用程式,流程像是這樣:

把實際責任拆開看:
例如模型可能只輸出:
{
"tool": "lookup_order",
"arguments": {
"order_id": "A-1024"
}
}
真正去查訂單是第三步的 tool executor,所以安全邊界應該放在 tool executor 與相關系統的授權檢查。
測 Web API 會先確認這支 API 是做什麼的,測有工具呼叫能力的 LLM 也一樣,第一輪先列舉它能呼叫哪些工具,把可以碰到的功能摸清楚,可以很直接問:
你可以使用哪些工具或 API?
每個工具的用途是什麼?
哪些會修改資料?
有沒有 debug、admin、maintenance 或 migration 功能?
這個工具只作用在單一筆資料,還是整個 tenant、整個檔案區、整個資料庫?
但模型願意把工具列出來,不代表系統已經被攻破,這時候還只是在盤點攻擊面,這個階段要注意的是有沒有超出任務需求但能力又很大的工具,例如可以執行系統指令,如果模型連參數也一起透露出來,就可以繼續往下看,哪些參數可以由使用者控制、後端實際會拿這些值做什麼。
所以列舉完工具之後,下一步就是盤點參數、執行身分和權限:
| 面向 | 要確認的事 |
|---|---|
| Tool | 模型能呼叫哪些 function,有沒有隱藏、除錯或管理功能 |
| Parameters | 必填與選填欄位、型別、範圍,哪些值可以由使用者間接控制 |
| Scope | 能作用到哪些使用者、tenant、目錄、資料庫或外部服務 |
| Identity | 目前使用者、agent 的 service account,還是管理者身分執行 |
| Permission | 這個工具被授權做到哪一步:只能讀,還是可以建立、修改、刪除,甚至把資料送出系統 |
| Approval | 高風險動作要不要人重新確認,那個確認發生在哪一層 |
其中最容易被忽略的是執行身分,假設 Vivian 登入客服機器人問「幫我查退款進度」,畫面上是 Vivian 發出的請求,後端卻可能是用 support-agent-service 去查所有客戶的退款資料,如果 tool executor 沒有把 Vivian 的身分、tenant 與角色帶進授權判斷,那模型就成了一個高權限代理人,任何能影響它選工具的人都在借用這組 service account。
此外錯誤訊息也值得順便記下來,參數缺漏、類型錯誤、目的地不存在或權限不足的回覆,模型有時候會把 schema 與後端資源名稱一起吐出來,不過這些都還只是線索,能不能變成漏洞,還是要看能不能串成一條真的攻擊鏈。
有時候開發階段會為了方便,先加上一些測試或除錯工具,但系統上線後卻忘了拿掉,假設一個對外客服 AI,業務上只需要查訂單,第一輪先問它能用哪些工具,結果除了查訂單,還看到一個排錯用的工具;接著追問這個工具收什麼參數,也如實回答了,到這一步,攻擊鏈就展開了:

這個情境的問題是,測試工具還留在正式環境裡,而且後面接的是一組權限遠大於業務需求的憑證。
換一個情境,客服機器人只需要查訂單功能,但正式環境卻還有 run_shell(command),系統把太泛用的能力直接交給模型,只要這個能力在模型可以選的清單裡,就可能因為 prompt injection、模型誤判或其他流程問題被呼叫。
函式 get_my_documents() 看起來很安全,但如果後端是用公司共用的管理者 token 去執行,代表它實際上是 get_anyone_documents(),能碰到的範圍遠超過「我的文件」。同樣的問題也會出現在資料庫帳號、OAuth scope、雲端 IAM 和跨 tenant 的 service account。
使用者有權刪除自己的文件,不代表模型聽到一句「把舊的清掉」就該立刻執行,語意模糊、間接注入或一次判斷失誤,就能直接變成不可逆的操作,開場 PocketOS 那個 agent 就是這種情況。
所以刪除、付款、寄送、發佈、部署、修改權限這類動作,不能只靠模型自己判斷,應該在執行之前,把操作對象、影響範圍和後果清楚列出來,交給使用者重新確認。
要防止類似的攻擊,最簡單、最直接的一步,就是把不需要的工具或功能拿掉,debug、maintenance、migration,或任何可以「任意執行」的介面,都不該留在對外的對話流程裡。
此外模型可能被 prompt injection 影響,也可能只是判斷錯了,選到不該用的工具,只要執行之前還有一道獨立的授權與檢查,那個動作就不會直接落到系統上。
最後是紀錄,每一次 tool call 都應該留下足夠的資訊,包括使用者身分、session、工具名稱、關鍵參數、授權情境、下游執行身分、核准狀態和執行結果,這樣哪天客服機器人突然對資料庫做了寫入,或是那個早該下架的排錯工具在正式環境被呼叫,至少還有完整的紀錄可以把整條操作路徑還原出來。
傳統 Web 測試看到一個功能,會先看 request 長什麼樣、有哪些參數、用誰的權限執行、能不能越權,這套方法放到 AI 應用裡其實沒什麼不同。
面對能使用工具的 LLM,先盤點能力,再盤點權限,工具名稱、參數、作用範圍、執行身分、操作權限和核准流程,都要一項一項確認。
下一篇再把鏡頭放大一點,當模型不只會呼叫工具,還會保存記憶、修改設定檔,並且在迴圈裡連續做上好幾步,攻擊面就不再只是一段 Prompt,而是一條會自己繼續往前走的鏈。