Home / Blog / Web Application Security Headers: A Practical Guide to Locking Down Your Site
Web Development

Web Application Security Headers: A Practical Guide to Locking Down Your Site

AJAjish Stephen August 8, 2026 7 min read
Web Application Security Headers: A Practical Guide to Locking Down Your Site

HTTP security headers are one of the highest-leverage, lowest-effort defenses available — a handful of response headers can block clickjacking, reduce XSS impact, and force HTTPS, all without touching your application logic. Here's what actually matters, with copy-paste config for both nginx and Laravel.

Content-Security-Policy (CSP)

Restricts which sources scripts, styles, and other resources can load from — the single most effective header against XSS impact:

# nginx
add_headerContent-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none';" always;
💡Start with Content-Security-Policy-Report-Only instead of the enforcing header while testing — it logs violations without blocking anything, so you can see what would break before you actually turn enforcement on.

Strict-Transport-Security (HSTS)

Tells browsers to only ever connect over HTTPS, even if a user types http:// or clicks an old link:

add_headerStrict-Transport-Security "max-age=31536000; includeSubDomains" always;

X-Frame-Options (clickjacking protection)

Prevents your site from being loaded inside an <iframe> on another domain — a common technique for tricking users into clicking something they didn't mean to:

add_headerX-Frame-Options "DENY" always;

X-Content-Type-Options

Stops browsers from trying to guess a file's type and executing it differently than the server intended — closes a class of MIME-sniffing attacks:

add_headerX-Content-Type-Options "nosniff" always;

Referrer-Policy and Permissions-Policy

Two more worth setting — controlling how much URL information leaks to other sites, and which browser features (camera, geolocation, etc.) your pages can request:

add_headerReferrer-Policy "strict-origin-when-cross-origin" always;
add_headerPermissions-Policy "geolocation=(), microphone=(), camera=()" always;

Setting all of these from Laravel instead

If you'd rather set headers at the application layer — useful when they need to vary by route — a simple middleware covers it:

namespaceApp\Http\Middleware;

useClosure;
useIlluminate\Http\Request;

classSecurityHeaders
{
  public functionhandle(Request$request, Closure$next)
  {
    $response=$next($request);

    $response->headers->set('X-Frame-Options','DENY');
    $response->headers->set('X-Content-Type-Options','nosniff');
    $response->headers->set('Referrer-Policy','strict-origin-when-cross-origin');
    $response->headers->set(
      'Content-Security-Policy',
      "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';"
    );

    return$response;
  }
}

Register it globally in your middleware stack so it applies to every response without needing to remember it per route.

Testing what you've set

After deploying, verify headers are actually present with a plain curl -I https://yoursite.com, or use one of the free online header-scanning tools to get a readable breakdown and grade. Don't assume the config took effect just because you saved the file — nginx needs a reload, and caching layers (CDNs, browser cache) can serve old headers for a while after a change.

Want your production infrastructure reviewed for gaps like this? This is part of what I cover in DevOps services engagements — infrastructure hardening alongside deployment and CI/CD work.

Common questions

Do security headers actually stop attacks, or just reduce risk?
They're a real defensive layer, not just a checkbox. A well-configured Content-Security-Policy can genuinely block an XSS payload from executing even if it made it into the page.
Should I set headers in nginx or in my application code?
Either works, but nginx-level headers apply to every response, including static assets and error pages, without depending on your application code running correctly.
What happens if I misconfigure Content-Security-Policy?
A too-strict CSP can silently break your own site. Always test with Content-Security-Policy-Report-Only first before switching to the enforcing header.
Is HSTS safe to enable on any site?
Only once you're certain your entire site will reliably serve over HTTPS going forward. Browsers cache this instruction, so a misconfiguration can be hard to undo.
Is your infrastructure actually hardened?
I review and harden production server configurations, not just app code.
Explore DevOps Services →
© Copyright 2024 Ajish Stephen