OWASPCheat Sheet

CS-DotNet_Security DotNet Security Cheat Sheet

Official page ↗
Project
OWASP Cheat Sheet Series

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. Keep the runtime and packages supported and patched. Follow the .NET security announcements, which include ASP.NET Core advisories.

Authentication and authorization

Use ASP.NET Core Identity or a supported identity provider integration. Do not implement password recovery or session management from scratch. 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. • 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`; do not call `KeyDerivation.Pbkdf2` directly to store passwords. • 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. • 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. Authentication cookies Configure Identity's application cookie through `ConfigureApplicationCookie`: • 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. • 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. • 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. 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. 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. 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. 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.

Input handling

SQL injection • 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. • 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. • 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. • 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. • 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. See Cross-Site Request Forgery Prevention for the threat model and controls beyond framework configuration. Cross-site scripting (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. 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. Serialization and 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. • 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. • For XML, disable unnecessary external resource resolution and follow the settings for your .NET parser. Defaults differ by API and framework version.

Data protection

Encryption for storage • For Windows-local secrets, `ProtectedData` uses the Windows Data Protection API (DPAPI). Choose the scope deliberately: user scope binds decryption to that account, while machine scope permits other accounts on that computer to decrypt. This does not protect against code running with the decrypting account's privileges. • Protect ASP.NET Core's Data Protection keys as well as the data they protect. When overriding key persistence, configure encryption at rest explicitly and restrict access to the key repository. • For other stored data, follow Cryptographic Storage. If using `AesGcm` directly, use the constructor with an explicit tag size and never reuse a nonce with the same key. 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.

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. • 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. • 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. • Use operating-system permissions and isolation for untrusted components. Code Access Security and partial trust are not supported security boundaries.

Legacy .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`. ASP.NET MVC and Web Forms • In MVC, generate tokens with `@Html.AntiForgeryToken()` and validate them with `[ValidateAntiForgeryToken]` on state-changing actions. For AJAX, follow Microsoft's Framework antiforgery guidance. • 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. • 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. 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. 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.

References