One easy and good start to harden your website or web application is to configure the HTTP Security Headers. Those HTTP Headers are included in the response of the server and tell the browser how to deal with content on your website.
First step: Check your HTTP Headers
First step is to check which HTTP headers are already configured and which should be added. Scott Helme build a great site for that: https://securityheaders.com/
After that, you can configure all missing headers.
Recommended HTTP Security Headers
The configuration of the Headers ALWAYS depend on your website, your requirements, the features, the structure etc.. Therefore, it is always up to you to check the headers in detail.
In many cases, the following headers are a good starting point:
Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self' Referrer-Policy: strict-origin-when-cross-origin Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Content-Type-Options: nosniff X-Frame-Options: deny X-Permitted-Cross-Domain-Policies: none
If you set the CSP, be careful and make sure that your site still works afterwards! Especially google-analytics or other external scripts will probably not load anymore!
# Allow everything, but only from the same origin default-src 'self'; # Allow scripts from origin and Google Analytics script-src 'self' www.google-analytics.com # Allow scripts, ajax, form actions, css and images from the same origin. default-src 'none'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'
Check your Content-Security-Policy with: https://csp-evaluator.withgoogle.com/
Get more information at:
This policy defines how much referrer information is included in requests. If you tweet a link to your website and visitors click this link, the header will contain the referrer information. If someone clicks a link on your webpage, the referrer information is also included. Two examples:
The second one only contains the root url, arminreiter.com, while the first one also has the page in it. Your referrer policy depends on which information you want to share with other websites, but it is at least recommended to only allow referrer information for websites that use HTTPS.
Note: The referrer policy can also be defined as meta tag in html or separately for each link:
<meta name="referrer" content="origin"> <!-- or --> <a href="https://arminreiter.com" rel="noreferrer">
The following values are allowed:
Referrer-Policy: no-referrer Referrer-Policy: no-referrer-when-downgrade Referrer-Policy: origin Referrer-Policy: origin-when-cross-origin Referrer-Policy: same-origin Referrer-Policy: strict-origin Referrer-Policy: strict-origin-when-cross-origin Referrer-Policy: unsafe-url
A description of the different options can be found here:
When the server returns a cookie to the client, the response contains a set-cookie header. This header can be extended with some attributes. The following one is a recommended Set-Cookie header:
Set-Cookie: name=value; Expires=date; Secure; HttpOnly; SameSite=Strict
The following attributes are allowed:
- Secure: is set when the request is made with https scheme.
- SameSite=Strict: Browser sends cookie only for same-site request. Other options are Lax and None.
Find more information about Set-Cookie at:
Tells the browser that the website should only be accessed via HTTPS.
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
- max-age: tells the browser to remember that the site is only accessible via HTTPS for this amount of time (in seconds). 31536000 = 1 year
- includeSubDomains (optional): rule is applied also to subdomains
- preload (optional): Google maintains an HSTS preload list (https://hstspreload.org/) which contains domains that have opted-in to HSTS and can therefore only be accessed over HTTPS.
This options prevents the browser from doing MIME-type sniffing. Thats a technique which is used by some browsers to determine the type of a file and execute it, independent of the returned content-type. If the browser e.g. requests a script, but that script has an incorrect media type, the browser will “sniff” the content of the file, detect it as script and execute it. An attacker could for example upload a script file with content-type image (e.g. as profile image of a user). The browser would sniff the content of the “image”, will detect that it is a script and will execute it.
This can be prevented by using the HTTP header:
Defines if the page can be rendered in an <embed>, <frame>, <iframe> or <object> tag. If someone creates a page with an iframe that embeds your webpage, then the options below will block the rendering of your page (by sure, it must be supported by the browsers, but most of them do). You can test this by creating a new page – e.g. index.html – on your desktop, and embed your website into an iframe:
<html> <body> <iframe src="https://arminreiter.com"> </iframe> </body> </html>
If you open this index.html, you will, instead of your webpage, see the following content in the iframe:
There are the following 2 options available (note: allow-from is deprecated and not supported by many browsers):
- X-Frame-Options: DENY
The page can not be displayed in a frame.
- X-Frame-Options: SAMEORIGIN
The site can only be displayed in a frame with the same origin.
Prevents others to embed your website e.g. into adobe flash applications or PDF documents. This can be completely forbidden or controlled via a crossdomain.xml policy file. The allowed values are:
- X-Permitted-Cross-Domain-Policies: none
Do not allow any embedding.
- X-Permitted-Cross-Domain-Policies: master-only
Instructs Flash and other applications to only read the master crossdomain.xml file from the root website.
- X-Permitted-Cross-Domain-Policies: by-content-type
Only policy files served with content type “text/x-cross-domain-policy” are allowed.
- X-Permitted-Cross-Domain-Policies: all
All policy files on the domain are required.
Extra: remove headers that expose information
Beside the headers mentioned above, there are other standard headers e.g. X-Powered-By, Server, X-AspNet-Version and others. They expose information about your website/infrastructure and should therefore be removed.
other HTTP Headers
X-XSS-Protection instructs the browser to stop pages from loading when they detect cross-site scripting (xss). This header is not supported by Chrome, Firefox or Edge and is therefore not needed anymore. Value could be:
X-XSS-Protection: 1; mode=block
- Can I use: https://caniuse.com/
- HTTP Headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/
- OWASP Secure Headers Project: https://owasp.org/www-project-secure-headers
- Security Headers Scan: https://securityheaders.com/