Skip to content

DotNet Security Cheat Sheet / .NET 安全速查表

Introduction / 介绍

This cheat sheet focuses on security decisions for modern .NET and ASP.NET Core. Guidance for existing .NET Framework applications is separated at the end.

本速查表专注于现代 .NET 和 ASP.NET Core 的安全决策。现有 .NET Framework 应用程序的指南位于末尾。

Keep the runtime and packages supported and patched. Follow the .NET security announcements, which include ASP.NET Core advisories.

保持运行时和包得到支持并修补。关注 .NET 安全公告,其中包含 ASP.NET Core 安全建议。

Authentication and authorization / 身份验证和授权

Use ASP.NET Core Identity or a supported identity provider integration. Do not implement password recovery or session management from scratch.

使用 ASP.NET Core Identity 或支持的身份提供者集成。不要从头实现密码恢复或会话管理。

Account protection / 账户保护

  • Use a store that supports lockout and enable it for the affected users (LockoutEnabled). Configure IdentityOptions.Lockout and pass lockoutOnFailure: true to PasswordSignInAsync so failed password attempts count toward lockout. See Identity lockout configuration.
    中文:使用支持锁定并启用它的存储库,为受影响的用户配置锁定(LockoutEnabled)。配置 IdentityOptions.Lockout 并将 lockoutOnFailure: true 传递给 PasswordSignInAsync,以便失败的密码尝试计入锁定。参见 身份锁定配置。
  • Apply login throttling and multifactor authentication. Protect registration and password recovery too; login lockout does not cover those flows.
    中文:应用 登录限制 和 多因素认证。也要保护注册和密码恢复;登录锁定不包括这些流程。
  • Return consistent authentication responses, including comparable timing, so login, registration, and recovery do not disclose whether an account exists.
    中文:返回一致的 身份验证响应,包括可比的时间,以便登录、注册和恢复不会泄露账户是否存在。

Passwords / 密码

  • Use Identity's PasswordHasher<TUser>; do not call KeyDerivation.Pbkdf2 directly to store passwords.
    中文:使用 Identity 的 PasswordHasher<TUser>;不要直接调用 KeyDerivation.Pbkdf2 来存储密码。
  • Configure PasswordHasherOptions.IterationCount for the hash algorithm used by your Identity version to meet the Password Storage Cheat Sheet's PBKDF2 guidance. Benchmark the work factor on the deployment hardware; do not assume the framework default meets current guidance.
    中文:配置 PasswordHasherOptions.IterationCount 以满足 Identity 版本使用的哈希算法的 密码存储作弊表 PBKDF2 指导。在部署硬件上基准测试工作因子;不要假设框架默认值符合当前指导原则。
  • Set IdentityOptions.Password.RequiredLength according to the password strength guidance. Disable the RequireDigit, RequireLowercase, RequireUppercase, and RequireNonAlphanumeric composition rules. Update scaffolded registration and password-reset validation to match; see Identity password configuration. Also screen for common and breached passwords; length and composition settings do not provide that check.
    中文:根据 密码强度指导 设置 IdentityOptions.Password.RequiredLength。禁用 RequireDigit、RequireLowercase、RequireUppercase 和 RequireNonAlphanumeric 组成规则。更新生成的注册和密码重置验证以匹配;参见 Identity 密码配置。还要筛选常见和泄露的密码;长度和组成设置不提供该检查。

Configure Identity's application cookie through ConfigureApplicationCookie:

通过ConfigureApplicationCookie配置Identity的应用程序cookie:

  • Set Cookie.HttpOnly = true and Cookie.SecurePolicy = CookieSecurePolicy.Always. Choose Cookie.SameSite to fit the authentication flow; test federated sign-in before tightening it. HttpOnly prevents script access to the cookie, but does not stop injected scripts from making authenticated requests.
    中文:设置Cookie.HttpOnly = true和Cookie.SecurePolicy = CookieSecurePolicy.Always。选择Cookie.SameSite以适应身份验证流程;在加强之前测试联合登录。HttpOnly防止脚本访问cookie,但不会阻止注入的脚本进行认证请求。
  • Set an appropriate ExpireTimeSpan. With SlidingExpiration = true, activity renews the authentication ticket; it is not an absolute session limit. See cookie authentication options and session expiration.
    中文:设置适当的 ExpireTimeSpan。当 SlidingExpiration = true 时,活动将续订身份验证票据;它不是绝对会话限制。请参阅 cookie 身份验证选项 和 会话过期。
  • Ensure security-sensitive changes update the user's security stamp, calling UserManager.UpdateSecurityStampAsync(user) when the operation does not already do so. Keep Identity's security stamp validation enabled. Existing cookies are rejected at the next stamp validation, subject to SecurityStampValidatorOptions.ValidationInterval; revocation is not necessarily immediate.
    中文:确保安全敏感的更改更新用户的身份验证戳,当操作本身不这样做时,调用 UserManager.UpdateSecurityStampAsync(user)。保持 Identity 的 安全戳验证 启用。在下一个戳验证时,现有 cookie 将被拒绝,受 SecurityStampValidatorOptions.ValidationInterval 的约束;撤销不一定是立即的。

Authorization / 授权

Prefer a fallback policy requiring authentication, and mark intentionally public endpoints with [AllowAnonymous] or AllowAnonymous(). It covers only requests that reach the authorization middleware; static files served earlier are not protected by it.

优先选择需要认证的回退策略,并使用[AllowAnonymous]或AllowAnonymous()标记故意公开的端点。它仅覆盖到达授权中间件的请求;之前提供的静态文件不受其保护。

Authentication alone does not grant permission. Apply role or named-policy requirements, such as [Authorize(Policy = "...")] or RequireAuthorization("..."), to privileged operations. Named policies do not inherit the fallback policy; include the authentication requirement.

仅身份验证并不授予权限。将角色或命名策略要求,如[Authorize(Policy = "...")]或RequireAuthorization("..."),应用于特权操作。命名策略不继承回退策略;包括认证要求。

For object-specific permissions, use IAuthorizationService.AuthorizeAsync with the resource and requested operation before returning or changing it. Neither the fallback policy nor an [Authorize] attribute alone performs this resource check. See Authorization and Insecure Direct Object Reference Prevention.

对于特定对象的权限,在使用IAuthorizationService.AuthorizeAsync之前,使用资源以及请求的操作,然后返回或更改它。回退策略或[Authorize]属性本身并不执行此资源检查。参见授权和防止不安全直接对象引用。

Redirects / 重定向

For local return URLs, use LocalRedirect or check Url.IsLocalUrl before redirecting. If external destinations are required, select them from a server-controlled allowlist; see Unvalidated Redirects and Forwards.

在重定向到本地返回URL之前,请使用LocalRedirect或检查Url.IsLocalUrl(https://learn.microsoft.com/en-us/aspnet/core/security/preventing-open-redirects?view=aspnetcore-10.0)。如果需要外部目标,请从服务器控制的允许列表中选择;参见未经验证的跳转和转发。

Input handling / 输入处理

SQL injection / SQL注入

  • Prefer Entity Framework LINQ queries. For SQL text, use the parameterized API supported by your EF Core version, such as FromSql or FromSqlInterpolated. Never concatenate untrusted values into SQL text passed to FromSqlRaw or other command APIs.
    中文:优先使用 Entity Framework LINQ 查询。对于 SQL 文本,使用您 EF Core 版本支持的 参数化 API,例如 FromSql 或 FromSqlInterpolated。永远不要将不受信任的值连接到传递给 FromSqlRaw 或其他命令 API 的 SQL 文本中。
  • Parameters represent values, not table or column names. Map any dynamic identifier to a fixed allowlist. Parameterization does not replace authorization or a database account with minimal privileges.
    中文:参数表示值,而不是表或列名。将任何动态标识符映射到固定的允许列表。参数化不能替代授权或具有最小权限的数据库账户。
  • See Query Parameterization and Database Security for examples and database access controls.
    中文:请参见查询参数化和数据库安全以获取示例和数据库访问控制信息。

OS command injection / 操作系统命令注入

See the .NET guidance in the OS Command Injection Defense Cheat Sheet.

请参阅操作系统命令注入防御指南。

Cross-site request forgery / 跨站请求伪造

When the browser sends credentials automatically, including cookies and Windows, Basic, or Digest authentication, protect state-changing operations with ASP.NET Core antiforgery validation. Do not change state in GET requests.

当浏览器自动发送凭据,包括cookies和Windows、Basic或Digest身份验证时,使用ASP.NET Core防伪造验证来保护状态更改操作。不要在GET请求中更改状态。

  • In MVC applications, register AutoValidateAntiforgeryTokenAttribute globally for unsafe HTTP methods. Razor Pages provide antiforgery protection by default. These MVC filters are not a substitute for the antiforgery configuration required by other endpoint types.
    中文:在MVC应用程序中,为不安全的HTTP方法全局注册AutoValidateAntiforgeryTokenAttribute。Razor Pages默认提供防伪造保护。这些MVC过滤器不能替代其他端点类型所需的防伪造配置。
  • Pair token generation with server-side validation. For forms not covered by automatic token generation, use @Html.AntiForgeryToken() explicitly. JavaScript requests must send the request token in the configured header or form field, along with the antiforgery cookie.
    中文:将令牌生成与服务器端验证配对。对于未由自动令牌生成覆盖的表单,显式使用@Html.AntiForgeryToken()。JavaScript请求必须在配置的头部或表单字段中发送请求令牌,以及防伪造cookie。
  • Do not add IgnoreAntiforgeryToken merely to make a failing request succeed. Verify how the endpoint authenticates requests and why CSRF protection is unnecessary before excluding it.
    中文:不要仅仅为了使失败的请求成功而添加IgnoreAntiforgeryToken。在排除它之前,验证端点如何验证请求以及为什么CSRF保护是不必要的。

See Cross-Site Request Forgery Prevention for the threat model and controls beyond framework configuration.

参见跨站请求伪造预防以了解威胁模型和框架配置之外的控件。

Cross-site scripting (XSS) / 跨站脚本(XSS)

Razor encodes ordinary variable output in HTML contexts. Do not bypass it with Html.Raw or HtmlString for untrusted content. HTML encoding does not make a value safe inside JavaScript, CSS, or a URL; follow the context-specific guidance in Cross-Site Scripting Prevention.

Razor 在HTML上下文中对普通变量输出进行编码。不要使用Html.Raw或HtmlString绕过它来处理不受信任的内容。HTML编码不会使值在JavaScript、CSS或URL中安全;遵循跨站脚本预防中的上下文特定指南。

Input validation is not a replacement for output encoding. If users must submit HTML, sanitize it with a maintained HTML sanitizer. Use Content Security Policy as an additional defense.

输入验证不能替代输出编码。如果用户必须提交HTML,请使用维护良好的HTML清理器进行清理。使用内容安全策略作为额外的防御措施。

Serialization and XML / 序列化和XML

  • Do not use BinaryFormatter; it cannot be made secure. Prefer a data-only format such as JSON with System.Text.Json, and deserialize into application-defined types. Validate the resulting values before use.
    中文:不要使用 BinaryFormatter;它无法被安全化。优先使用如 JSON 的数据格式,并使用 System.Text.Json 反序列化到应用程序定义的类型。在使用前验证结果值。
  • Review serializer-specific risks in the .NET deserialization guidance. A different serializer does not remove the need to validate data or constrain custom converters and type selection.
    中文:在.NET反序列化指南中审查序列化器的特定风险。不同的序列化器并不能消除验证数据或约束自定义转换器和类型选择的必要性。
  • For XML, disable unnecessary external resource resolution and follow the settings for your .NET parser. Defaults differ by API and framework version.
    中文:对于XML,禁用不必要的对外部资源的解析,并遵循你的.NET解析器的设置。默认值因API和框架版本而异。

Data protection / 数据保护

Encryption for storage / 存储加密

Encryption for transmission / 传输加密

Use TLS, not a custom key-exchange protocol. For browser applications, configure UseHttpsRedirection and UseHsts, or enforce them at the reverse proxy. APIs should reject insecure HTTP requests; a redirect cannot undo disclosure in the original request. See Transport Layer Security.

使用TLS,而不是自定义密钥交换协议。对于浏览器应用程序,配置UseHttpsRedirection和UseHsts(https://learn.microsoft.com/en-us/aspnet/core/security/enforcing-ssl),或在反向代理中强制执行。API应拒绝不安全的HTTP请求;重定向不能撤销原始请求中的披露。参见传输层安全。

Configuration and deployment / 配置和部署

  • Keep secrets out of source code and checked-in configuration. Use User Secrets only for development; it is not encrypted storage. Obtain production credentials from a managed secret store. Follow Secrets Management.
    中文:将密钥从源代码和已签入的配置中移除。仅将 User Secrets 用于开发;它不是加密存储。从受管理的密钥存储库中获取生产凭据。遵循 密钥管理。
  • Run production applications outside the Development environment. Use exception handling middleware and return generic errors; keep stack traces, credentials, and request details out of responses.
    中文:在生产环境中运行应用程序时,请勿使用 Development 环境。使用 异常处理中间件 并返回通用错误;确保堆栈跟踪、凭证和请求详情不包含在响应中。
  • Apply HTTP security headers in the application or reverse proxy, with one place responsible for each policy. Avoid copying a generic header configuration without testing the application's requirements.
    中文:在应用程序或反向代理中应用HTTP安全头,每个策略由一个地方负责。避免在没有测试应用程序需求的情况下复制通用的头配置。
  • Use operating-system permissions and isolation for untrusted components. Code Access Security and partial trust are not supported security boundaries.
    中文:使用操作系统权限和隔离措施处理不受信任的组件。代码访问安全性和部分信任不是支持的安全边界。

Legacy .NET Framework / 旧版.NET Framework

For secrets, .NET Framework 4.7.1 and later can use Configuration Builders to load values from external sources instead of embedding them in web.config.

对于密钥,.NET Framework 4.7.1及以后版本可以使用配置构建器从外部源加载值,而不是将它们嵌入到web.config中。

ASP.NET MVC and Web Forms / ASP.NET MVC和Web窗体

  • In MVC, generate tokens with @Html.AntiForgeryToken() and validate them with [ValidateAntiForgeryToken] on state-changing actions. For AJAX, follow Microsoft's Framework antiforgery guidance.
    中文:在 MVC 中,使用 @Html.AntiForgeryToken() 生成令牌,并在状态更改操作中使用 [ValidateAntiForgeryToken] 验证它们。对于 AJAX,遵循 Microsoft 的框架反伪造指南。
  • In Web Forms, set ViewStateUserKey during Page_Init or OnInit to an unpredictable value unique to the session. This helps protect ViewState postbacks; endpoints that do not validate ViewState still need CSRF protection.
    中文:在 Web Forms 中,在 Page_Init 或 OnInit 期间将 ViewStateUserKey 设置为 会话的唯一不可预测值。这有助于保护视图状态回发;即使端点未验证视图状态,也需要 CSRF 保护。
  • Keep production debugging and tracing disabled and configure custom error responses. Use context-appropriate output encoding; request validation alone does not prevent XSS. See ASP.NET request validation.
    中文:保持生产环境中的调试和跟踪功能禁用,并配置自定义错误响应。使用上下文适当的输出编码;仅请求验证无法防止 XSS。参见 ASP.NET 请求验证。

Forms authentication / 表单身份验证

In Forms Authentication settings, set cookieless="UseCookies", requireSSL="true", and an appropriate timeout. This keeps authentication tickets out of URLs and restricts their cookies to HTTPS.

在表单身份验证设置中,设置cookieless="UseCookies",requireSSL="true",以及适当的timeout。这会将身份验证票据从URL中排除,并限制它们的cookie使用HTTPS。

Windows Communication Foundation (WCF)

Choose a binding and security mode that provide the required confidentiality and authentication. WCF bindings and security documents their differences: BasicHttpBinding is unsecured by default but supports HTTPS when configured; TransportWithMessageCredential combines transport protection with message credentials. Do not assume a binding name or HTTP method alone secures a service.

选择一个提供所需机密性和身份验证的绑定和安全模式。WCF 绑定和安全 文档说明了它们之间的差异:BasicHttpBinding 默认情况下是不安全的,但配置后支持 HTTPS;TransportWithMessageCredential 结合了传输保护和消息凭证。不要假设绑定名称或 HTTP 方法本身就能保证服务安全。

References / 参考