Back to Blog

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.

Nodesty Team6 min readSecurity
The words Security Headers with HSTS, CSP and nosniff on a dark Nodesty background

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.

HeaderWhat does it do?Example value
Strict-Transport-SecurityMakes the browser open the site only over HTTPS (HSTS)max-age=31536000; includeSubDomains
X-Content-Type-OptionsStops the browser from guessing the file typenosniff
X-Frame-OptionsStops the page from being loaded in a frame on other sitesSAMEORIGIN
Referrer-PolicyWhich address information is passed on with links to other sitesstrict-origin-when-cross-origin
Permissions-PolicyRestricts browser features such as the camera, microphone and locationcamera=(), microphone=(), geolocation=()
Content-Security-PolicyDefines which sources scripts, styles and images can be loaded fromSite-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. 31536000 is 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 the frame-ancestors setting 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:

  1. Add the rule first with the Content-Security-Policy-Report-Only header. In this mode the browser doesn't block anything; it only logs the sources that violate the rule to the console.
  2. Browse every page of your site and note the CSP warnings in the browser console.
  3. Add the sources you actually need to the rule.
  4. 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_header line to a location block, that block stops inheriting all of the add_header lines from the level above. In location blocks 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 with include.

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 (or Strict): 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.

Nodesty

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

Launch your server now.

Build, scale, and conquer without limits on Nodesty's premium infrastructure.

                                                                                                                                                                                                                            
                                                                                                                                                                                                                            
                                                                                                                                                                                                                            
                                                                                                                             ············································                                                   
                                                ··································································································..........···························                                     
                                       ················..........................................................................................................................··············                             
                                  ·············.................::::::::::::::::::::::::::::::::::::::::::::::....................:::::::::::::::::::::::::::::::::::::::................···········                        
                             ············................:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::............·········                     
                         ············.................:::::::::::::::::::::::::::::::::::::::::::::::::::------------::::::::::::::::::::::::::::::----------------:::::::::::::::::::::..........········                  
                    ············......................::::::::::::::::::::::::::::::::::::------------------------------------------------------------------------------------:::::::::::::.........········                
                ··········.............................................::::::::::::::::::-------------==========================================-----------------------------------:::::::::::........·······               
             ········..................:.....................................::::::::::--------=======+++++++++++++++++++++++++++++++++++++=========================------------------::::::::::.......·······              
           ······.........::::::::::::::::::::................................:::::::-----=====++++xxxxxx**************************xxxxxxxxx++++++++++++++===================------------::::::::.......·······             
          ·····.......:::::::::::::::::::::::::::.............................:::::----===+++xxx****%%%%&&&&&&#############&&&&&&&%%%%%*******xxxxxxxx++++++++++++++==============----------:::::::......······             
         ····......::::::::-------------:::::::::::..........................::::---===+++xx***%%%&&&####@@@@@@@@@@@@@@@@@@@@@@@@####&&&&&%%%%*******xxxxxxxxx+++++++++++++===========--------::::::......·····             
        ····.....:::::::--------------------:::::::::.......................::::---===++xxx**%%&&&###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###&&&&%%%%%********xxxxxxxxxxx++++++++++++========------::::::.....······            
        ····.....:::::--------------------------::::::::....................::::---===++xx***%%&&&####@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@###&&&&&%%%%%**********xxxxxxxxxxxxx+++++++++=======------:::::.....·····            
        ····....::::::-------=============---------:::::::::................:::::---===+++xx***%%%&&&#####@@@@@@@@@@@@@@@@@@@@@@@@@#####&&&&&%%%%%%*************xxxxxxxxxxxxxx+++++++++======-----:::::....·····            
         ····....:::::-------================---------:::::::::...............:::::----===++++xxx***%%%%&&&&&&#################&&&&&&%%%%%%%*******************xxxxxxxxxxxxxxxxx++++++++======----:::::....·····            
         ·····....:::::--------=================---------::::::::::..............:::::::-----====+++++xxxxxx**************************xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx++++++++=====-----::::....·····            
          ·····.....:::::--------=================----------:::::::::::.................:::::::::-------=============++++++++++++++++++++++++++++++++++++xxxxxxxxxxxxxxxxxxxxxxx++++++++======-----::::....·····            
            ·····.....:::::::----------===========-------------::::::::::::.........................::::::::::::::::::------------------=============+++++++++++++++++++++++++++++++++=======-----::::.....·····            
              ······......:::::::---------------------------------:::::::::::::........................................:::::::::::::::-----------============+++++++++++++++++++++========------:::::.....·····             
                 ······........:::::::::---------------------------:::::::::::::::::...........................................:::::::::::::------------=============================--------::::::.....······              
                    ·········.........:::::::::::::::-------------::::::::::::::::::::::::.......................................::::::::::::::::--------------------------------------::::::::......·······                
                          ··········............::::::::::::::::::::::::::::::::::::::::::::::::::................................::::::::::::::::::::::::::-------------:::::::::::::::.........········                   
                                  ············..................:::::::::::::::::::::::::::::::::::::::::::.........................:::::::::::::::::::::::::::::::::::::................···········                        
                                             ················.............................................................................................................·················                                 
                                                           ······················................................................................···························                                                
                                                                               ·········································································