Security is a critical aspect of any ASP.NET Core application. Following best practices ensures that your APIs and web applications are protected against attacks such as SQL injection, XSS, CSRF, and data breaches. Below are the key security measures.
1. Use HTTPS Everywhere (SSL/TLS)
Enforce HTTPS to protect data in transit
Redirect HTTP to HTTPS in the Program.cs
app.UseHttpsRedirection();
Configure HSTS (HTTP Strict Transport Security) to prevent downgrade attacks.
app.UseHsts();
2. Secure Authentication & Authorization
Use JWT (JSON Web Token) Authentication
JWT is the most common method for securing APIs.
Configure JWT in the Program.cs.
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://your-auth-server.com";
options.Audience = "your-api";
});
Use Role-Based or Policy-Based Authorization.
[Authorize(Roles = "Admin")]
public IActionResult GetAdminData()
{
// Implementation here
}
Or using policies.
services.AddAuthorization(options =>
{
options.AddPolicy("RequireAdmin", policy => policy.RequireRole("Admin"));
});
Use OAuth2 & OpenID Connect for Identity Management
Consider Azure AD, IdentityServer4, or Auth0 for managing authentication.
3. Protect Against SQL Injection
Use Parameterized Queries or Entity Framework Core
Never concatenate user input in SQL queries. Use EF Core LINQ.
var user = await _context.Users
.Where(u => u.Email == email)
.FirstOrDefaultAsync();
Or Parameterized Queries.
var query = "SELECT * FROM Users WHERE Email = @Email";
var user = dbContext.Users.FromSqlRaw(query, new SqlParameter("@Email", email));
4. Prevent Cross-Site Scripting (XSS)
Enable Output Encoding to prevent script injection.
@Html.Encode(Model.UserInput)
Use Content Security Policy (CSP) in the Program.cs.
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Content-Security-Policy", "default-src 'self'");
await next();
});
Never trust user input in HTML fields.
5. Prevent Cross-Site Request Forgery (CSRF)
CSRF attacks force users to execute unwanted actions. Enable CSRF protection.
services.AddControllersWithViews().AddRazorPages().AddMvcOptions(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Use AntiForgeryToken in Razor Pages.
<form method="post">
@Html.AntiForgeryToken()
</form>
6. Secure API Endpoints
Use API Keys for External Access
Require API keys for third-party integrations.
if (context.Request.Headers.TryGetValue("X-API-KEY", out var extractedApiKey))
{
if (!apiKeyService.IsValid(extractedApiKey))
{
context.Response.StatusCode = 401;
return;
}
}
Implement Rate Limiting to Prevent DDoS Attacks
Use AspNetCoreRateLimit for rate-limiting.
services.Configure<IpRateLimitOptions>(options =>
{
options.GeneralRules = new List<RateLimitRule>
{
new RateLimitRule
{
Endpoint = "*",
Limit = 100,
Period = "1m"
}
};
});
7. Secure Sensitive Data
Store Secrets Securely
Never store sensitive data in appsettings.json. Instead, use.
- Azure Key Vault
- Environment Variables
- User Secrets (dotnet user-secrets)
- Example Environment Variable Configuration.
var connectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING");
Encrypt Connection Strings
Use Azure Key Vault or DPAPI to encrypt connection strings.
8. Implement Strong Logging & Monitoring
- Use Serilog or NLog for structured logging.
- Enable Application Insights in Azure for real-time monitoring.
Log Suspicious Activities
_logger.LogWarning("Suspicious login attempt from IP: {IP}", request.IP);
Avoid Logging Sensitive Information
// ❌ Bad Practice: Logging passwords
_logger.LogInformation("User {Email} attempted login with password {Password}");
9. Secure File Uploads
Restrict Allowed File Types
var allowedExtensions = new[] { ".jpg", ".png", ".pdf" };
if (!allowedExtensions.Contains(Path.GetExtension(file.FileName)))
{
return BadRequest("Invalid file type.");
}
Store Files Securely (Not in wwwroot).
Save files to cloud storage (Azure Blob, AWS S3) instead of exposing them.
Keep Framework & Dependencies Updated
Regularly update ASP.NET Core and NuGet packages.
dotnet outdated
dotnet add package --update
Use Dependency Scanning Tools.
- OWASP Dependency-Check
- GitHub Dependabot
Conclusion
Security is not a one-time implementation- it requires continuous monitoring and updating. By following these best practices, you can harden your ASP.NET Core application against attacks and vulnerabilities.