HTTP Security Headers: HSTS, CSP and More
What are HTTP security headers? HSTS, Content-Security-Policy, X-Content-Type-Options, Referrer-Policy, adding them with Nginx and .htaccess, and testing.

Contents
HTTP security headers are rules that your web server sends with every page, telling the browser how to handle the page securely. Protections such as forcing the site to open only over HTTPS, stopping the page from being secretly shown in a frame on other sites and blocking scripts that aren't allowed from running are added with a few lines of configuration.
This guide covers the most important security headers, what each one does, how to add them with Nginx and .htaccess, how to apply Content-Security-Policy without breaking your site, and how to test the headers.
Recommended headers
| Header | What does it do? | Example value |
|---|---|---|
Strict-Transport-Security | Makes the browser open the site only over HTTPS (HSTS) | max-age=31536000; includeSubDomains |
X-Content-Type-Options | Stops the browser from guessing the file type | nosniff |
X-Frame-Options | Stops the page from being loaded in a frame on other sites | SAMEORIGIN |
Referrer-Policy | Which address information is passed on with links to other sites | strict-origin-when-cross-origin |
Permissions-Policy | Restricts browser features such as the camera, microphone and location | camera=(), microphone=(), geolocation=() |
Content-Security-Policy | Defines which sources scripts, styles and images can be loaded from | Site-specific |
HSTS: Strict-Transport-Security
HSTS tells the browser to open your site only over HTTPS for a set period. Even if the user types the address with http:// or clicks an old link, the browser goes straight to HTTPS; this makes it harder to intercept the connection in its very first moment.
Strict-Transport-Security: max-age=31536000; includeSubDomains
max-age: How long the rule is valid, in seconds.31536000is one year.includeSubDomains: Applies the rule to all subdomains. Don't add this option if you have a subdomain without HTTPS.
Watch out: Browsers remember the HSTS rule for the duration of max-age. Try it with a short duration first (for example max-age=300), and only extend it once you're sure HTTPS works everywhere on your site and your subdomains. The preload option, which gets your site added to the HSTS list built into browsers, is a step that's hard to undo; don't use it unless you're sure what you're doing. We cover setting up SSL in our What is an SSL certificate? article.
X-Content-Type-Options, X-Frame-Options and Referrer-Policy
These three headers can be added to almost any site without risk:
X-Content-Type-Options: nosniff: Stops the browser from trying to guess a file's type; for example, it prevents a file loaded as an image from being run as a script.X-Frame-Options: SAMEORIGIN: Allows your page to be loaded in a frame only on your own site. This blocks attacks where your page is placed in an invisible frame and users are tricked into clicking without realizing it (clickjacking). If your site needs to be embedded on another site, use theframe-ancestorssetting in CSP.Referrer-Policy: strict-origin-when-cross-origin: On links to other sites, passes on only the domain name, not the full page address. If your addresses carry session information or personal data, this keeps it from leaking.
Permissions-Policy
It turns off browser features your site doesn't use. Even if a script added to your site is compromised, it can't access the camera, microphone or location:
Permissions-Policy: camera=(), microphone=(), geolocation=()
If your site uses one of these features (for example location for a store finder), remove that feature from the list or allow it only for your own domain: geolocation=(self).
Content-Security-Policy (CSP)
CSP is the most powerful header, but also the one that takes the most care to configure. It tells the browser which sources scripts, styles, fonts, images and connections can be loaded from. Sources that aren't allowed are blocked; this makes it harder for a script injected into your site to run or send data.
A simple starting rule:
Content-Security-Policy: default-src 'self'; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'
If you use analytics, ad, chat or payment tools, you have to add their domains to the relevant rules; otherwise they won't work.
Applying CSP without breaking your site:
- Add the rule first with the
Content-Security-Policy-Report-Onlyheader. In this mode the browser doesn't block anything; it only logs the sources that violate the rule to the console. - Browse every page of your site and note the CSP warnings in the browser console.
- Add the sources you actually need to the rule.
- When no warnings are left, change the header to
Content-Security-Policy.
Adding headers in Nginx
Add these to your server block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
always: Makes sure the header is sent on error pages too.- An important trap: In Nginx, if you add your own
add_headerline to alocationblock, that block stops inheriting all of theadd_headerlines from the level above. Inlocationblocks where you add something like a cache header, write the security headers again too, or collect the headers in a shared file and add them withinclude.
Then run sudo nginx -t and sudo systemctl reload nginx. We cover the basics of Nginx in our Nginx installation guide.
Adding them with .htaccess on web hosting
On hosting that uses Apache or LiteSpeed, add them to the .htaccess file in the site's root folder:
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>
A single typo in the .htaccess file can make the whole site return a 500 error; back up the file before making changes and check your site right after. If you get an error, see the steps in our HTTP error codes article.
Secure settings for cookies
Session cookies are as important as security headers. Make sure these attributes are turned on for your application's session cookies:
Secure: The cookie is only sent over HTTPS connections.HttpOnly: The cookie can't be accessed with JavaScript; an injected script can't steal the session cookie.SameSite=Lax(orStrict): Limits the cookie from being sent with requests coming from other sites.
WordPress, Laravel and other common software mostly set these themselves when HTTPS is used; if you're writing your own application, check them in the session settings.
Testing
curl -I https://yourdomain.com
The command lists the headers your site sends. You can also see a page's response headers in the Network tab of the developer tools that open with F12 in the browser. Test sites such as securityheaders.com list missing headers and recommendations when you enter your address.
Security headers are one layer of protection; up-to-date software, strong passwords and regular backups are still the basic protection. We cover general security steps for your own server in our Linux server security checklist.
Security headers at Nodesty
On Nodesty web hosting plans, the LiteSpeed web server supports .htaccess rules; you can add security headers to your .htaccess file from the file manager and use HSTS safely with free SSL. Imunify360 also stops malicious requests before they reach your site. If you manage your own web server on an AMD Ryzen 9 9950X VPS, you can define all of the headers however you like in your Nginx configuration.
Frequently Asked Questions
Do security headers protect my site from being hacked?
Not on their own. Security headers limit the impact of some types of attack by giving the browser extra rules; for example, they stop a page from being secretly loaded in a frame on another site, or unexpected scripts from running. Up-to-date software, strong passwords and backups are still the basic protection.
Can I go back after turning on HSTS?
Browsers remember the HSTS rule for the duration of max-age. You can remove the rule by setting the duration to 0, but this only takes effect in browsers that visit the site again. That's why you should try HSTS with a short duration first and only extend it once you're sure HTTPS works without problems everywhere on your site.
Can Content-Security-Policy break my site?
Yes. CSP blocks scripts, styles, fonts and images from sources that aren't allowed. External sources such as analytics, ad and chat tools won't work if they're not on the list. Try it first with the Content-Security-Policy-Report-Only header and widen the rule based on the warnings in the browser console.
Should I add the X-XSS-Protection header?
No. This header turned on a protection used in old browsers, and current browsers don't support it. The real protection against XSS is handling user input correctly and a well-configured Content-Security-Policy.
How do I add security headers on web hosting?
On hosting that uses Apache or LiteSpeed, you can add them with Header always set lines in the .htaccess file in the site's root folder. In WordPress, some security plugins also let you add these headers from their settings.
How do I check whether the headers are working?
You can look at the page's response headers in the Network tab of the browser's developer tools, see the headers on the command line with curl -I, or enter your address on a test site such as securityheaders.com to list the missing headers.
About the author
Nodesty Team · Infrastructure & Support
The Nodesty team runs our servers, network and DDoS protection day to day and answers customer support requests around the clock. These guides come from that work.
Related articles

How to Use UFW: An Ubuntu Firewall Guide
How to use UFW on Ubuntu: enabling the firewall safely, port and IP rules, deleting rules, application profiles, rate limiting, IPv6 and Docker.

What Is an SSH Tunnel? A Port Forwarding Guide
What is an SSH tunnel and how do you set one up? Local, remote and dynamic port forwarding, secure database and panel access, ~/.ssh/config and autossh.

Website Hacked? What to Do, Step by Step
Website hacked? What to do: the signs, first response, passwords, finding malicious files, restoring a clean backup, WordPress cleanup and prevention.