Contents

Trust Boundary Violation 風險問題

以前我第一次看到弱掃工具跳出 Trust Boundary Violation,第一個反應其實是「我明明只是拿 request 參數查資料,怎麼也會被報」。後來回頭整理才發現,這類問題不是指程式一定已經被打穿,而是提醒我們不要把外部輸入直接當成可信任資料往下傳。

簡單來說,只要資料是從 HTTP request、Cookie、Header、Query String、檔案上傳、訊息佇列,甚至別的系統 API 回傳進來,都應該先視為不可信任。程式如果沒有做驗證、過濾或型別限制,就直接拿去查資料庫、拼接路徑、寫檔案或輸出到頁面,就很容易被弱掃工具標記。

什麼是 Trust Boundary

Trust Boundary 可以理解成「資料從不可信任區域,跨進可信任程式邏輯的邊界」。

常見例子像這些:

  1. 使用者輸入的帳號、姓名、查詢條件。
  2. 前端送來的 JSON 欄位。
  3. 第三方系統 callback 回來的參數。
  4. 上傳檔案的檔名、MIME type、路徑。

這些值一旦直接進入核心流程,就可能衍生出 SQL Injection、XSS、Path Traversal、業務規則繞過,或至少讓弱掃無法確認這段程式是安全的。

為什麼弱掃會報

弱掃工具通常不是在判斷「你有沒有出事」,而是在判斷「資料流是否有明確被驗證」。

像下面這種寫法就很容易被標:

1
2
String userId = request.getParameter("userId");
userService.findUser(userId);

就算 findUser 內部最後是用 prepared statement,弱掃有時還是會認為這個值跨越 trust boundary 後沒有先被驗證,因此繼續往下標記。

實務上的修補方向

修這類問題時,我自己通常會先做三件事:

  1. 先限制型別,例如該是數字就轉成數字,該是 Enum 就轉成 Enum。
  2. 再限制格式,例如長度、字元白名單、是否允許空值。
  3. 最後才交給 service 或 repository 使用。

如果只是單純說「有做 filter」其實不太夠,因為真正重點是要讓資料在邊界進來時就被收斂成可控格式。

Java 範例

下面是比較容易讓人理解的作法,先把 request 參數驗證完再往下傳:

1
2
3
4
5
6
7
8
String rawUserId = request.getParameter("userId");

if (rawUserId == null || !rawUserId.matches("^[0-9]{1,10}$")) {
	throw new IllegalArgumentException("userId 格式錯誤");
}

long userId = Long.parseLong(rawUserId);
User user = userService.findUser(userId);

如果專案本身有用 Bean Validation、Spring Validation,或者統一的 request DTO,通常會更好維護,不一定要每次手刻正規表示式。

ESAPI Validator 可以怎麼用

如果舊專案本來就有導入 OWASP ESAPI,也可以利用 Validator 做基礎驗證,例如限制最大長度、允許字元集合、是否必填。不過我自己會把它當成其中一層保護,不會把所有安全議題都壓在同一個 validator 上。

重點不是「用了哪個函式庫」,而是:

  1. 邊界輸入有沒有先驗證。
  2. 驗證規則是否符合業務需求。
  3. 後續資料庫、檔案、HTML 輸出是否還有各自的安全處理。

我後來的整理

這個風險很多時候不是要你亂加一堆 filter,而是要把輸入資料整理成明確、可驗證、可維護的格式。只要做到「邊界先驗證、內部用強型別、輸出再依情境做編碼」,通常弱掃結果就會乾淨很多,後續維護的人也比較看得懂這段程式到底信任了什麼。

參考資料