Securing a SaaS web application requires layers of defense. While securing your database and validating API inputs are critical, you can secure your front-facing interface against a large class of client-side vulnerabilities using HTTP security headers.
These headers tell the browser how to behave when rendering your site, helping block cross-site scripting (XSS), clickjacking, and packet sniffing.
This guide lists the critical security headers every SaaS developer should configure and how to set them up.
1. Five Critical Security Headers
Ensure your server responds with these 5 recommended security headers:
Strict-Transport-Security (HSTS)
HSTS forces the browser to communicate with your site exclusively over secure HTTPS connections. It prevents attackers from downgrading connections to unencrypted HTTP during redirect phases.
- Example Value:
max-age=31536000; includeSubDomains; preload - Warning: Only enable this once you have verified your SSL certificate works correctly across all subdomains, as disabling it after activation is difficult.
Content-Security-Policy (CSP)
CSP is a powerful security header that dictates which resources (scripts, stylesheets, images, connections) the browser is allowed to load. It blocks XSS attacks by refusing to run scripts from untrusted domains.
- Example Value:
default-src 'self'; script-src 'self' https://trusted-apis.com; style-src 'self' 'unsafe-inline'; - Tip: Implementing a strict CSP can be complex due to inline scripts used by analytics or chat widgets. Start in report-only mode (
Content-Security-Policy-Report-Only) to log violations before enforcing them.
X-Frame-Options / frame-ancestors
These control whether your website can be embedded in an <iframe> on external sites. This is the primary defense against clickjacking, where attackers overlay an invisible iframe of your site to hijack user clicks.
- X-Frame-Options (Legacy):
SAMEORIGIN(restricts framing to your domain only). - CSP frame-ancestors (Modern):
frame-ancestors 'self' https://partner-site.com(allows specific, trusted domains to frame your app, which is helpful for integrations).
X-Content-Type-Options
Forces the browser to respect the Content-Type header sent by the server instead of attempting to "sniff" or guess the file type. This prevents attackers from uploading malicious scripts disguised as image files.
- Value:
nosniff
Referrer-Policy
Controls how much referrer information (the URL from which a user clicked a link) is passed to external sites when navigating away from your app.
- Value:
strict-origin-when-cross-origin(sends the full URL for same-origin requests, but only the domain origin for cross-origin requests).
2. Server Configuration Examples
Here is how you can declare these headers across common server environments:
Next.js (next.config.js)
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
],
},
];
},
};
Nginx Config
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
3. Auditing Your Security Headers
Missing security headers are highlighted during security audits and compliance checks (such as SOC2).
Verify your headers configuration by inputting your URL into the HTTP Headers Checker. It provides a 5-point security score, verifies individual policy presence, and organizes your headers into categories for easy review.
- Audit your application: HTTP Headers Checker