What are security headers?
HTTP security headers are response headers your web server sends to browsers to restrict what the browser is allowed to do with your page. They are a lightweight, high-value defence against a range of common attacks including cross-site scripting (XSS), clickjacking, and protocol downgrade attacks.
They require no changes to your application code — just a small server configuration update.
What to do
Headers checked by ExposureIndex
Strict-Transport-Security (HSTS)
Tells browsers to always use HTTPS for your domain — even if the user types http://.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age— How long (in seconds) the browser should enforce HTTPS. One year (31536000) is the recommended minimum.includeSubDomains— Also enforce on all subdomains.preload— Optional: allows submission to the browser preload list so HSTS is enforced even on the very first visit.
Content-Security-Policy (CSP)
Restricts which resources (scripts, styles, images, fonts) a page can load and from where. A strict CSP is the most effective browser-side defence against XSS.
A basic starting policy for a simple site:
Content-Security-Policy: default-src 'self'; img-src 'self' data:; font-src 'self'; script-src 'self'; style-src 'self'
CSP is complex and requires tuning for your specific application. Start with Content-Security-Policy-Report-Only to observe violations without blocking, then enforce once confirmed.
If you use external scripts or css like Bootstrap or similar, hosted on their CDN, you will need to include those URL's in the CSP, or else the css or javascripts won't be used. An alternative is to host the external javascripts and css on your webserver.
X-Content-Type-Options
Prevents browsers from guessing ("sniffing") the content type of a response, which can lead to XSS via uploaded files.
X-Content-Type-Options: nosniff
Always set this. It has no downsides.
X-Frame-Options
Prevents your page from being embedded in an <iframe> on another site — the basis of clickjacking attacks.
X-Frame-Options: DENY
Or, if you need your own site to embed pages in iframes:
X-Frame-Options: SAMEORIGIN
Referrer-Policy
Controls how much referrer information the browser sends when a user clicks a link away from your site.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
Restricts access to browser features like the camera, microphone, geolocation, and payment APIs.
Permissions-Policy: camera=(), microphone=(), geolocation=()
Adding headers in common web servers
Nginx:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Apache:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Flask (Python):
@app.after_request
def set_security_headers(response):
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
return response
Last updated: March 28, 2026