ASP.NET Core Application Security Essentials Print

  • 0

ASP.NET Core Application Security

Essential security practices for ASP.NET 8 LTS/9/10 applications.

1. Authentication Configuration

Cookie Authentication Security

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Cookie.HttpOnly = true;        // Prevent JS access
        options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS only
        options.Cookie.SameSite = SameSiteMode.Strict; // Prevent CSRF
        options.ExpireTimeSpan = TimeSpan.FromHours(8);
        options.SlidingExpiration = true;
    });

JWT Token Security

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!))
        };
    });

2. CSRF Protection

Enable Anti-Forgery Tokens

// In Program.cs
builder.Services.AddAntiforgery(options =>
{
    options.HeaderName = "X-CSRF-TOKEN";
    options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});

// In controllers
[ValidateAntiForgeryToken]
public IActionResult UpdateProfile(ProfileModel model) { ... }

In Razor Views

<form method="post">
    @Html.AntiForgeryToken()
    <!-- form fields -->
</form>

3. Input Validation

Model Validation Attributes

public class UserRegistration
{
    [Required]
    [StringLength(100, MinimumLength = 2)]
    public string Name { get; set; }

    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 8)]
    [RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$",
        ErrorMessage = "Password must contain upper, lower, and number")]
    public string Password { get; set; }
}

Controller Validation

[HttpPost]
public IActionResult Register(UserRegistration model)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    // Process valid input
}

4. XSS Prevention

Output Encoding (Automatic in Razor)

<!-- Safe - automatically encoded -->
<p>@Model.UserInput</p>

<!-- Dangerous - only use for trusted HTML -->
@Html.Raw(Model.TrustedHtml)

Manual Encoding

using System.Text.Encodings.Web;

var encoder = HtmlEncoder.Default;
var safeOutput = encoder.Encode(userInput);

5. Rate Limiting (ASP.NET 7+)

// In Program.cs
builder.Services.AddRateLimiter(options =>
{
    options.AddFixedWindowLimiter("Api", opt =>
    {
        opt.PermitLimit = 100;
        opt.Window = TimeSpan.FromMinutes(1);
        opt.QueueLimit = 0;
    });
});

app.UseRateLimiter();

// On endpoints
[EnableRateLimiting("Api")]
public class ApiController : ControllerBase { }

6. Secrets Management

User Secrets (Development)

# Initialize
dotnet user-secrets init

# Set secret
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=..."

Environment Variables (Production)

// Access in code
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION");

// Or via configuration
var connectionString = builder.Configuration["ConnectionStrings:DefaultConnection"];

7. Secure File Uploads

[HttpPost]
public async Task<IActionResult> Upload(IFormFile file)
{
    // Validate file type
    var allowedExtensions = new[] { ".jpg", ".png", ".pdf" };
    var extension = Path.GetExtension(file.FileName).ToLowerInvariant();

    if (!allowedExtensions.Contains(extension))
        return BadRequest("Invalid file type");

    // Validate file size (5MB max)
    if (file.Length > 5 * 1024 * 1024)
        return BadRequest("File too large");

    // Generate safe filename
    var safeFileName = $"{Guid.NewGuid()}{extension}";

    // Save outside web root
    var path = Path.Combine(_uploadsPath, safeFileName);
    using var stream = new FileStream(path, FileMode.Create);
    await file.CopyToAsync(stream);

    return Ok();
}

Security Configuration Checklist

Item Status
HTTPS enforced ☐
Security headers configured ☐
CSRF protection enabled ☐
Input validation on all forms ☐
Authentication properly configured ☐
Secrets not in source code ☐
File uploads validated ☐
Rate limiting enabled ☐
Error pages hide sensitive info ☐

Was this answer helpful?

« Back