Secure Your .NET Web Applications
Security is a fundamental aspect of building robust web applications with .NET. This guide covers the core concepts, built‑in frameworks, and best practices you need to protect your applications from common threats.
Key Topics
- Authentication – Verifying the identity of a user.
- Authorization – Determining what an authenticated user can do.
- Data Protection – Encrypting data at rest and in transit.
- CSRF & XSS Prevention – Mitigating injection attacks.
- Secure Headers – Using HTTP security headers.
- Logging & Auditing – Tracking security‑relevant events.
Authentication
.NET provides flexible authentication options, from simple cookie authentication to OpenID Connect and OAuth 2.0. Use the Microsoft.AspNetCore.Authentication
package to configure schemes in Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => {
options.LoginPath = "/Account/Login";
options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
options.SlidingExpiration = true;
});
services.AddAuthorization(options => {
options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
});
}
Authorization
Leverage [Authorize]
attributes and policies to protect actions and resources:
[Authorize(Roles = "Admin")]
public IActionResult AdminDashboard()
{
return View();
}
[Authorize(Policy = "CanEdit")]
public IActionResult Edit(int id)
{
// ...
}
Data Protection
Use the DataProtection
API to protect sensitive data like authentication tokens:
var protector = provider.CreateProtector("MyPurpose");
string protectedPayload = protector.Protect("SensitiveData");
string original = protector.Unprotect(protectedPayload);
Cross‑Site Request Forgery (CSRF)
.NET MVC and Razor Pages automatically generate anti‑forgery tokens. Ensure they are validated in POST actions:
@Html.AntiForgeryToken()
<form method="post">
<!-- form fields -->
</form>
Content Security Policy (CSP)
Set CSP headers to mitigate XSS and data injection attacks:
app.Use(async (context, next) =>
{
context.Response.Headers["Content-Security-Policy"] =
"default-src 'self'; script-src 'self' https://trusted.cdn.com;";
await next();
});
Secure Headers
Header | Value |
---|---|
Strict-Transport-Security | max-age=31536000; includeSubDomains |
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Referrer-Policy | no-referrer |
Logging & Auditing
Integrate ILogger
with structured logging (e.g., Serilog) to capture security events:
public class AccountController : Controller
{
private readonly ILogger<AccountController> _logger;
public AccountController(ILogger<AccountController> logger) { _logger = logger; }
[HttpPost]
public async Task Login(LoginViewModel model)
{
if (!ModelState.IsValid) return View(model);
var result = await _signInManager.PasswordSignInAsync(...);
if (result.Succeeded)
{
_logger.LogInformation("User {User} logged in successfully.", model.Email);
return RedirectToAction("Index", "Home");
}
_logger.LogWarning("Failed login attempt for {User}.", model.Email);
// ...
}
}