跳到正文
>_ITDITDWeb 安全平台

按框架

ASP.NET Core 安全 — 生产环境加固实务参考

ASP.NET Core 生产环境加固参考:优先级清单,外加生产环境错误、密钥(User Secrets/Key Vault)、NuGet CVE、授权、over-posting、反序列化与 SSRF。以防御为主,不含攻击步骤。

发布于 2026-07-02 更新于 2026-07-02 3 分钟阅读

面向:在 ASP.NET Core 上运营应用或 API 的人。这里不讲攻击步骤——这是一份用于加固的实务参考:优先级排序的清单、分领域指引、以及自查。要看跨框架的全局,请参阅 按框架的安全防护入口

优先级排序的加固清单

按此表自上而下执行。P0 是前提,P1 是最频繁的事故来源,P2 是持续的运营卫生。

P0 ── 前提(先做这个)

生产环境不显示详细错误 / 把密钥外置 / 快速为 NuGet 依赖 CVE 打补丁

P1 ── 最主要的事故来源

授权([Authorize]、默认拒绝、所有者)/ over-posting 防御(DTO/[Bind])

P2 ── 运营卫生

不安全的反序列化 / HTTPS、响应头、antiforgery / SSRF

从地基往上加固:P0(前提)→ P1(最主要的事故来源)→ P2(运营卫生)。
优先级控制项具体做法(ASP.NET Core)
P0生产环境错误UseExceptionHandler。生产环境不显示 Developer Exception Page/详情(正确的环境判断)
P0密钥外置不要硬编码在 appsettings.json。开发 = User Secrets,生产 = 环境变量/Key Vault
P0NuGet 依赖 CVEdotnet list package --vulnerable/osv-scanner 监控;以运行中的版本判定,快速打补丁
P1显式授权[Authorize] + 默认拒绝(回退策略)+ 基于资源/所有者的检查
P1over-posting 防御绑定到 DTO,而非直接绑定实体。用 [Bind] 限制接受的字段
P2反序列化不要用 BinaryFormatter。不要用不安全的格式还原不受信任的数据
P2HTTPS/响应头/CSRFUseHttpsRedirectionUseHsts、antiforgery(CSRF)、Cookie 属性
P2SSRF服务端取回用允许列表 + 阻断内部 IP/元数据

1. 生产环境错误暴露(P0)

  • 在生产环境,通过 UseExceptionHandler 切换到通用的错误页,并不显示 Developer Exception Page/详情(把环境判断做对,例如 ASPNETCORE_ENVIRONMENT=Production)。
  • 不要把堆栈跟踪或内部结构泄露到外部。

2. 把密钥外置(P0)

  • 不要把连接字符串或密钥硬编码在 appsettings.json 里。开发环境用 User Secrets,生产环境用环境变量或云端密钥管理器(Key Vault)
  • appsettings.json 容易经由误提交或暴露而泄露。不要把它提交到仓库,也不要放进公开目录(→ 不要把密钥放进公开目录)。泄露时及时轮换。

3. NuGet 依赖 CVE(P0)

  • dotnet list package --vulnerable 或 osv-scanner 机器监控已知 CVE,以运行中的版本判定,并快速打补丁(→ 监控依赖包的 CVE · 漏洞应对实务)。
  • .NET 保持在受支持的版本,不要放着 EOL 版本不管。

4. 授权(P1 — 最主要的来源)

常见(危险)

  • 在端点上忘了加 [Authorize]
  • 已认证,但没有所有者检查
  • 默认倾向“允许”,未认证也能通过
  • 没有角色/策略设计,检查零零散散

正确

  • [Authorize] + 通过回退策略实现默认拒绝
  • 基于角色/策略 + 基于资源的授权以确认所有权
  • 每一条读取/更新/删除路径上核验
  • 授权显式构建,不交给默认值

参阅 IDOR 是什么。认证和授权是两回事;在靠近数据的地方做授权。

5. over-posting(P1)

  • **不要直接绑定实体。**绑定到一个仅供输入的 DTO,只接受你需要的字段。
  • 或者用 [Bind] 显式限制接受的字段。不要让某个权限标志被外部输入覆写。

6. 不安全的反序列化与输入(P2)

  • 不要用 BinaryFormatter(过时/不安全)。不要用不安全的格式还原不受信任的数据(在特定条件下可能导致 RCE)(→ RCE 是什么)。
  • 在使用前,用**模型校验(data annotations 等)**校验输入的类型/范围/允许值。

7. HTTPS、响应头、antiforgery(P2)

  • UseHttpsRedirection + UseHsts 强制 HTTPS,并把 Cookie 标记为 secure/httponly/samesite。
  • 在表单/会更改状态的请求上使用 antiforgery 令牌(CSRF 防御)(→ CSRF 是什么)。
  • 加上安全响应头(用 安全响应头检查器 检查你自己的站点)。

8. SSRF 与服务端取回(P2)

  • 服务端(HttpClient 等)取回用户提供的 URL 时,应把目标限制在允许列表,并阻断到内部 IP/元数据的访问(→ SSRF 是什么)。校验上传,并把它们存放在公开面之外。

验证:你的 ASP.NET Core 真的加固了吗

做完不算完——检查过才算完成。以下是针对你自己环境的防御性自查。

1

生产环境没有 Developer Exception Page

在生产环境故意触发一个错误,确认详情(堆栈 / Developer Exception Page)不会对外显示。
2

密钥不在配置/仓库里

确认连接字符串/密钥没有硬编码在 appsettings.json 里,且仓库里没有任何密钥。
3

授权是否有效

在测试环境里,请求别的用户的资源,确认被拒绝(读取/更新/删除)。
4

依赖与 HTTPS/响应头

确认 dotnet list package --vulnerable/osv 干净,并通过响应头检查器确认 HTTPS/HSTS 存在。

本站的视角:即便地基稳固,配置和授权仍归你自己

ASP.NET Core 在认证、授权和 Data Protection 方面机制稳固,但生产环境配置把授权落地,是你必须按环境、按端点逐一做对的东西。本站是另一套技术栈,但原则是一样的:生产环境不泄露内部信息、把密钥放在配置之外、在所有对外入口都写好授权、并监控依赖的 CVE。稳固的地基,只有配上正确的配置和显式的授权才能兑现价值。

接下来读

FAQ

Q要保护 ASP.NET Core,第一步该做什么?
A

P0 的三件事:(1) 生产环境不显示 Developer Exception Page / 详细错误(UseExceptionHandler,正确的环境判断);(2) 把密钥外置,而非硬编码在 appsettings.json 里(开发用 User Secrets,生产用环境变量或 Key Vault);(3) 用机器监控 NuGet 依赖 CVE 并快速打补丁,以运行中的版本判定。接着再进入授权([Authorize]、默认拒绝)与 over-posting 防御。

Q密钥(连接字符串、API 密钥)应该放在哪里?
A

规则是:不要硬编码在 appsettings.json 里。开发环境用 User Secrets;生产环境从环境变量或云端密钥管理器(Key Vault)加载。appsettings.json 往往最终会进入仓库,并容易经由公开目录或误提交而泄露。一旦泄露,请及时轮换连接字符串或密钥。

Q如何防止忘记加授权特性?
A

在控制器或端点上忘了加 [Authorize],任何人都能未经认证就访问它。把默认倾向设为拒绝(用回退策略拒绝未认证的请求),用基于角色/策略的授权把权限写明确,并编写资源所有者检查(基于资源的授权)。不要止步于“已登录=允许”——还要验证目标对象的所有者。

Q什么是 over-posting?
A

如果模型绑定把每个字段都接收进实体,用户发送的意料之外的字段(比如某个权限标志)就可能被覆写——这就是 over-posting。修复办法是绑定到一个仅供输入的 DTO,或用 [Bind] 显式限制接受的字段。不要直接绑定实体。

Q为什么不安全的反序列化很危险?
A

用像 BinaryFormatter 这样不安全的反序列化器还原不受信任的数据,在特定条件下可能导致远程代码执行(RCE)。BinaryFormatter 已被视为过时/不安全——不要使用它。要核实外部来源数据的出处,必要时限制为一种安全的格式(例如配置得当的 JSON)。