各框架對策
ASP.NET Core 的資安對策 — 正式環境強化實務參考
ASP.NET Core 的正式環境強化參考:優先度清單,加上正式環境錯誤、秘密(User Secrets/Key Vault)、NuGet CVE、授權、過度接收、還原序列化與 SSRF。以防禦視角撰寫,不含攻擊步驟。
對象:正在 ASP.NET Core 上維運應用程式或 API 的人。這裡不談攻擊步驟——這是用來強化的可實作參考:依優先度排序的清單、各領域指引與自我檢查。想看跨框架的全貌,請參閱 各框架資安對策的入口。
依優先度排序的強化清單
由上往下逐項處理這張表。P0 是前提,P1 是最頻繁的事故來源,P2 是持續性的維運衛生。
P0 ── 前提(先做這個)
正式環境不顯示詳細錯誤/把秘密外部化/迅速修補 NuGet 相依套件 CVE
P1 ── 最主要的事故來源
授權([Authorize]、預設拒絕、擁有者)/過度接收防禦(DTO/[Bind])
P2 ── 維運衛生
不安全的還原序列化/HTTPS、標頭、antiforgery/SSRF
| 優先度 | 對策 | 具體(ASP.NET Core) |
|---|---|---|
| P0 | 正式環境錯誤 | UseExceptionHandler。正式環境不顯示開發者例外頁面/細節(正確的環境判定) |
| P0 | 把秘密外部化 | 別寫死在 appsettings.json。開發=User Secrets,正式環境=環境/Key Vault |
| P0 | NuGet 相依套件 CVE | 以 dotnet list package --vulnerable/osv-scanner 監控;以實際執行版本判定,迅速修補 |
| P1 | 明確的授權 | [Authorize]+預設拒絕(fallback policy)+資源型/擁有者檢查 |
| P1 | 過度接收防禦 | 繫結到 DTO,而非直接繫結實體。用 [Bind] 限制接收的欄位 |
| P2 | 還原序列化 | 別用 BinaryFormatter。別用不安全的格式還原不可信的資料 |
| P2 | HTTPS/標頭/CSRF | UseHttpsRedirection、UseHsts、antiforgery(CSRF)、cookie 屬性 |
| P2 | SSRF | 伺服器端取得採允許清單+阻擋內部 IP/中繼資料 |
1. 正式環境錯誤的外露(P0)
- 在正式環境用
UseExceptionHandler切換到通用錯誤,並不顯示開發者例外頁面/細節(把環境判定做對,例如ASPNETCORE_ENVIRONMENT=Production)。 - 別把堆疊追蹤或內部結構外洩到外部。
2. 把秘密外部化(P0)
- **別把連線字串或金鑰寫死在 appsettings.json。開發用 User Secrets,正式環境從環境變數或雲端秘密管理(Key Vault)**載入。
- appsettings.json 容易經由誤 commit 或暴露而外洩。別把它 commit 進 repo,也別放在公開目錄(→ 別把秘密放在公開目錄)。外洩就立即輪替。
3. NuGet 相依套件 CVE(P0)
- 用
dotnet list package --vulnerable或 osv-scanner 以機器監控已知 CVE,以實際執行的版本判定,迅速修補(→ 監控相依套件的 CVE · 漏洞應變實務手冊)。 - 把 .NET 保持在受支援的版本,別放任 EOL 版本。
4. 授權(P1——最主要的來源)
常見(危險)
- 端點上忘了加
[Authorize] - 已驗證,但沒有擁有者檢查
- 預設傾向「允許」,未驗證的請求直接通過
- 沒有角色/政策設計,臨時性地檢查
正確
[Authorize]+以 fallback policy 做預設拒絕- 角色/政策為基礎+以資源型授權確認擁有者
- 在每一條讀取/更新/刪除路徑上驗證
- 授權是明確地寫出來,而非交給預設
參閱 IDOR 是什麼。驗證與授權是兩回事;在貼近資料的地方授權。
5. 過度接收(P1)
- **別直接繫結實體。**繫結到僅供輸入的 DTO,只接收你需要的欄位。
- 或用
[Bind]明確限制接收的欄位。別讓權限旗標從外部輸入被覆寫。
6. 不安全的還原序列化與輸入(P2)
- 別用
BinaryFormatter(過時/不安全)。別用不安全的格式還原不可信的資料(在特定條件下可能導致 RCE)(→ RCE 是什麼)。 - 在使用前,用**模型驗證(data annotations 等)**驗證輸入的型別/範圍/允許值。
7. HTTPS、標頭、antiforgery(P2)
- 用
UseHttpsRedirection+UseHsts強制 HTTPS,並把 cookie 標記為 secure/httponly/samesite。 - 在表單/會變更狀態的請求上使用 antiforgery token(CSRF 防禦)(→ CSRF 是什麼)。
- 加上安全標頭(用 安全標頭檢測 檢查自己的網站)。
8. SSRF 與伺服器端取得(P2)
- 伺服器端(
HttpClient等)取得使用者提供的 URL 時,應把目標限制為允許清單並阻擋觸及內部 IP/中繼資料(→ SSRF 是什麼)。驗證上傳,並存到公開面之外。
檢驗:你的 ASP.NET Core 真的強化了嗎?
做完不是終點——檢查過才算完成。以下是針對你自己環境的防禦性自我檢查。
正式環境不出現開發者例外頁面
秘密不在設定/repo 裡
appsettings.json,且 repo 裡沒有秘密。授權有效
相依套件與 HTTPS/標頭
dotnet list package --vulnerable/osv 為乾淨,且透過 標頭檢測 確認有 HTTPS/HSTS。本站的觀點:即使地基穩固,設定與授權仍在你身上
ASP.NET Core 具備完善的認證、授權與資料保護機制,但正式環境設定與套用授權,是你必須依環境、依端點各自做對的事。本站是不同的技術棧,但原則相同:正式環境不外洩內部資訊、把秘密放在設定之外、在公開入口一定要寫授權、對相依套件監控 CVE。穩固地基的價值,唯有在設定正確與授權明確之下才發揮得出來。
接下來讀
- 入口:各框架資安對策 · Spring Boot 資安對策(同為企業級、相依套件/授權的型態相近)
- 實務:漏洞應變實務手冊 · 監控相依套件的 CVE · 別把秘密放在公開目錄
- 名詞:IDOR 是什麼 · RCE 是什麼 · CSRF · SSRF
- 工具:安全標頭檢測
FAQ
Q要保護 ASP.NET Core,第一步該做什麼?
三個 P0 項目:(1) 在正式環境別顯示開發者例外頁面/詳細錯誤(UseExceptionHandler、正確的環境判定);(2) 把秘密外部化,而非寫死在 appsettings.json(開發用 User Secrets,正式環境用環境變數或 Key Vault);(3) 用機器監控 NuGet 相依套件的 CVE 並迅速修補,以實際執行的版本判定。接著再進到授權([Authorize]、預設拒絕)與過度接收的防禦。
Q秘密(連線字串、API 金鑰)該放哪裡?
原則是:不要寫死在 appsettings.json。開發時用 User Secrets;正式環境從環境變數或雲端秘密管理(Key Vault)載入。appsettings.json 容易被納入 repo,也容易經由公開目錄或誤 commit 而外洩。萬一外洩,要立即輪替連線字串或金鑰。
Q要如何防止忘記加授權屬性?
在控制器或端點上忘了加 [Authorize],任何人都能不經驗證就到達。把預設傾向『拒絕』(用 fallback policy 擋掉未驗證的請求)、以角色/政策為基礎把權限寫明確,並寫上資源擁有者的檢查(resource-based authorization)。別停在『已登入=允許』——連操作目標的擁有者也要驗證。
Q什麼是過度接收(over-posting)?
若模型繫結把每個欄位都接收進實體,使用者送出的未預期欄位(例如權限旗標)就可能被覆寫——這就是過度接收。修法是繫結到僅供輸入的 DTO,或用 [Bind] 明確限制接收的欄位。別直接繫結實體。
Q為什麼不安全的還原序列化很危險?
用像 BinaryFormatter 這種不安全的還原序列化器還原不可信的資料,在特定條件下可能導致遠端程式碼執行(RCE)。BinaryFormatter 被視為過時/不安全——別用它。驗證外部來源資料的出處,並在需要時限制為安全的格式(例如妥善設定的 JSON)。