跳至主要內容
>_ITDITD網站資安平台

各框架對策

ASP.NET Core 的資安對策 — 正式環境強化實務參考

ASP.NET Core 的正式環境強化參考:優先度清單,加上正式環境錯誤、秘密(User Secrets/Key Vault)、NuGet CVE、授權、過度接收、還原序列化與 SSRF。以防禦視角撰寫,不含攻擊步驟。

發布於 2026-07-02 更新於 2026-07-02 閱讀時間 3 分鐘

對象:正在 ASP.NET Core 上維運應用程式或 API 的人。這裡不談攻擊步驟——這是用來強化的可實作參考:依優先度排序的清單、各領域指引與自我檢查。想看跨框架的全貌,請參閱 各框架資安對策的入口

依優先度排序的強化清單

由上往下逐項處理這張表。P0 是前提,P1 是最頻繁的事故來源,P2 是持續性的維運衛生。

P0 ── 前提(先做這個)

正式環境不顯示詳細錯誤/把秘密外部化/迅速修補 NuGet 相依套件 CVE

P1 ── 最主要的事故來源

授權([Authorize]、預設拒絕、擁有者)/過度接收防禦(DTO/[Bind])

P2 ── 維運衛生

不安全的還原序列化/HTTPS、標頭、antiforgery/SSRF

從地基往上強化:P0(前提)→ P1(最主要的事故來源)→ P2(維運衛生)。
優先度對策具體(ASP.NET Core)
P0正式環境錯誤UseExceptionHandler。正式環境不顯示開發者例外頁面/細節(正確的環境判定)
P0把秘密外部化別寫死在 appsettings.json。開發=User Secrets,正式環境=環境/Key Vault
P0NuGet 相依套件 CVEdotnet list package --vulnerable/osv-scanner 監控;以實際執行版本判定,迅速修補
P1明確的授權[Authorize]預設拒絕(fallback policy)+資源型/擁有者檢查
P1過度接收防禦繫結到 DTO,而非直接繫結實體。用 [Bind] 限制接收的欄位
P2還原序列化別用 BinaryFormatter。別用不安全的格式還原不可信的資料
P2HTTPS/標頭/CSRFUseHttpsRedirectionUseHsts、antiforgery(CSRF)、cookie 屬性
P2SSRF伺服器端取得採允許清單+阻擋內部 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)

  • UseHttpsRedirectionUseHsts 強制 HTTPS,並把 cookie 標記為 secure/httponly/samesite。
  • 在表單/會變更狀態的請求上使用 antiforgery token(CSRF 防禦)(→ CSRF 是什麼)。
  • 加上安全標頭(用 安全標頭檢測 檢查自己的網站)。

8. SSRF 與伺服器端取得(P2)

  • 伺服器端(HttpClient 等)取得使用者提供的 URL 時,應把目標限制為允許清單阻擋觸及內部 IP/中繼資料(→ SSRF 是什麼)。驗證上傳,並存到公開面之外。

檢驗:你的 ASP.NET Core 真的強化了嗎?

做完不是終點——檢查過才算完成。以下是針對你自己環境的防禦性自我檢查。

1

正式環境不出現開發者例外頁面

在正式環境故意觸發錯誤,確認細節(堆疊/開發者例外頁面)不會對外顯示
2

秘密不在設定/repo 裡

確認連線字串/金鑰沒有寫死在 appsettings.json,且 repo 裡沒有秘密。
3

授權有效

在測試環境中,請求別的使用者的資源,確認它被拒絕(讀取/更新/刪除)。
4

相依套件與 HTTPS/標頭

確認 dotnet list package --vulnerable/osv 為乾淨,且透過 標頭檢測 確認有 HTTPS/HSTS。

本站的觀點:即使地基穩固,設定與授權仍在你身上

ASP.NET Core 具備完善的認證、授權與資料保護機制,但正式環境設定套用授權,是你必須依環境、依端點各自做對的事。本站是不同的技術棧,但原則相同:正式環境不外洩內部資訊、把秘密放在設定之外、在公開入口一定要寫授權、對相依套件監控 CVE。穩固地基的價值,唯有在設定正確與授權明確之下才發揮得出來。

接下來讀

FAQ

Q要保護 ASP.NET Core,第一步該做什麼?
A

三個 P0 項目:(1) 在正式環境別顯示開發者例外頁面/詳細錯誤(UseExceptionHandler、正確的環境判定);(2) 把秘密外部化,而非寫死在 appsettings.json(開發用 User Secrets,正式環境用環境變數或 Key Vault);(3) 用機器監控 NuGet 相依套件的 CVE 並迅速修補,以實際執行的版本判定。接著再進到授權([Authorize]、預設拒絕)與過度接收的防禦。

Q秘密(連線字串、API 金鑰)該放哪裡?
A

原則是:不要寫死在 appsettings.json。開發時用 User Secrets;正式環境從環境變數或雲端秘密管理(Key Vault)載入。appsettings.json 容易被納入 repo,也容易經由公開目錄或誤 commit 而外洩。萬一外洩,要立即輪替連線字串或金鑰。

Q要如何防止忘記加授權屬性?
A

在控制器或端點上忘了加 [Authorize],任何人都能不經驗證就到達。把預設傾向『拒絕』(用 fallback policy 擋掉未驗證的請求)、以角色/政策為基礎把權限寫明確,並寫上資源擁有者的檢查(resource-based authorization)。別停在『已登入=允許』——連操作目標的擁有者也要驗證。

Q什麼是過度接收(over-posting)?
A

若模型繫結把每個欄位都接收進實體,使用者送出的未預期欄位(例如權限旗標)就可能被覆寫——這就是過度接收。修法是繫結到僅供輸入的 DTO,或用 [Bind] 明確限制接收的欄位。別直接繫結實體。

Q為什麼不安全的還原序列化很危險?
A

用像 BinaryFormatter 這種不安全的還原序列化器還原不可信的資料,在特定條件下可能導致遠端程式碼執行(RCE)。BinaryFormatter 被視為過時/不安全——別用它。驗證外部來源資料的出處,並在需要時限制為安全的格式(例如妥善設定的 JSON)。