Web applications face a class of attacks that are independent of the language or framework: CSRF (Cross-Site Request Forgery), clickjacking, MIME sniffing, and XSS (Cross-Site Scripting). HTTP security headers are the browser-enforced defence โ they instruct browsers to refuse certain behaviours. A Content-Security-Policy header tells the browser which scripts are allowed to run. X-Frame-Options prevents your site from being embedded in an iframe for clickjacking. X-Content-Type-Options: nosniff prevents MIME-type sniffing attacks. Adding these headers costs nothing and eliminates entire vulnerability categories.
Security Headers Middleware
// โโ Custom middleware for security headers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public class SecurityHeadersMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context)
{
// Prevent MIME type sniffing
context.Response.Headers["X-Content-Type-Options"] = "nosniff";
// Prevent clickjacking โ disallow embedding in iframes
context.Response.Headers["X-Frame-Options"] = "DENY";
// XSS protection (legacy header for older browsers)
context.Response.Headers["X-XSS-Protection"] = "1; mode=block";
// Control referrer information sent with requests
context.Response.Headers["Referrer-Policy"] = "strict-origin-when-cross-origin";
// Restrict browser features (camera, mic, geolocation)
context.Response.Headers["Permissions-Policy"] =
"camera=(), microphone=(), geolocation=(), payment=()";
// HSTS (also set via UseHsts middleware โ belt and suspenders for API responses)
if (context.Request.IsHttps)
context.Response.Headers["Strict-Transport-Security"] =
"max-age=31536000; includeSubDomains";
// Content Security Policy โ most powerful XSS defence
// For an API: restrict to self and no inline scripts
context.Response.Headers["Content-Security-Policy"] =
"default-src 'self'; " +
"script-src 'self'; " +
"style-src 'self'; " +
"img-src 'self' data: https:; " +
"font-src 'self'; " +
"connect-src 'self'; " +
"frame-ancestors 'none'; " + // equivalent to X-Frame-Options: DENY for modern browsers
"base-uri 'self'; " +
"form-action 'self'";
await next(context);
}
}
// Register early in the pipeline
app.UseMiddleware<SecurityHeadersMiddleware>();
Content-Security-Policy-Report-Only) before enforcing it.X-Frame-Options: DENY if your application legitimately embeds content in iframes (dashboards, embedded widgets). And do not blindly copy-paste CSP headers from examples โ an overly restrictive CSP breaks legitimate application functionality (Angular SPA scripts, fonts, API calls). Test every CSP change thoroughly in development and staging before production deployment. Broken CSP in production blocks all users from loading the application.Anti-Forgery Tokens for Non-API Applications
// โโ For Razor Pages/MVC โ CSRF protection is automatic โโโโโโโโโโโโโโโโโโโ
// Form posts include an anti-forgery token validated by [ValidateAntiForgeryToken]
// โโ For API-only applications โ CSRF is generally not needed โโโโโโโโโโโโโ
// Pure JSON APIs using Bearer token (JWT) authentication are not vulnerable
// to CSRF attacks because:
// - Browsers do not auto-send Authorization headers (unlike cookies)
// - CORS policy restricts which origins can make requests
// - Pre-flight OPTIONS requests further restrict cross-origin access
//
// HOWEVER: If your API uses cookie-based authentication (not JWT):
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-Token"; // Angular sends token in this header
options.SuppressXFrameOptionsHeader = false; // keep X-Frame-Options header
});
// Middleware to validate anti-forgery for cookie-auth API requests
app.UseAntiforgery();
Common Mistakes
Mistake 1 โ Not adding security headers (easy wins left on the table)
โ Wrong โ API deployed without any security headers; fails security audits and compliance checks.
โ Correct โ add the SecurityHeadersMiddleware shown above as a baseline for every ASP.NET Core application.
Mistake 2 โ Overly restrictive CSP breaking Angular SPA
โ Wrong โ CSP blocks Angular’s runtime script loading, breaking the entire application.
โ Correct โ test CSP in report-only mode first; audit blocked resources; add necessary sources before enforcing.