12 security headers you should use to prevent Vulnerabilities.

Security is as important as the website’s content and SEO, and thousands of websites are hacked because of misconfiguration or lack of security. If you are a website owner or security engineer looking to protect your website from attacks by clickjacking, code injection, MIME types, cross site scripting, cookie hijacking etc. then this article will help you in a great way.

Please take a backup of apache/nginx configuration file prior making changes. Some of the headers may not be supported on older browsers, so check out the compatibility before the implementation.

Mod_headers need be enabled in Apache if you are going implement these headers to Apache. You can execute below command in shell with root to enable mod_headers.

~$ sudo a2enmod headers
~$ sudo service apache2 restart

you can use online security header analysing tool to verify the results before and after.

List of Secure HTTP Headers

  1. HTTP Strict Transport Security
  2. X-XSS-Protection
  3. X-Frame-Options
  4. X-Content-Type-Options
  5. HTTP Public Key Pinning
  6. Content Security Policy
  7. X-Permitted-Cross-Domain-Policies
  8. Referrer Policy
  9. Expect-CT
  10. Feature-Policy
  11. Cookies with HttpOnly and secure Flags
  12. Same-Site Cookie Attribute

1. HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security (HSTS) is a web security policy mechanism which helps to protect websites against protocol downgrade attacks and cookie hijacking. It allows web servers to declare that web browsers (or other complying user agents) should only interact with it using secure HTTPS connections, and never via the insecure HTTP protocol. HSTS is an IETF standards track protocol and is specified in RFC 6797. A server implements an HSTS policy by supplying a header (Strict-Transport-Security) over an HTTPS connection (HSTS headers over HTTP are ignored).

HSTS is a critical header and it will be cached in the browser and if site have unsecure resources then it will be blocked which can create issues for you customer. Before implementing this header, you must ensure all your website page is accessible over HTTPS else they will be blocked.

Below are the parameters it takes

ValueDescription
max-age=SECONDSThe time, in seconds, that the browser should remember that this site is only to be accessed using HTTPS.
includeSubDomainsIf this optional parameter is specified, this rule applies to all of the site’s subdomains as well.
preloadThis is basically getting your website and or domain on an approved HSTS list that is actually built into the browser. Google officially compiles this list and it is utilized by Chrome, Firefox, Opera, Safari, IE11, and Edge. Submit your site to the official HSTS preload list.

For HSTS preload you must meet some additional requirements to be eligible.

  • The server must have a valid SSL/TLS certificate.
  • Redirect all traffic to HTTPS.
  • Serve HSTS on the base domain.
  • Serve all subdomains over HTTPS, specifically including the www subdomain if it exists.
  • Expiry must be at least 1 year (31536000 seconds)
  • The includeSubdomains token directive must be specified
  • The preload token directive must be specified.

let’s take an example of having HSTS configured for one year including preload for domain and sub-domain.

Apache HTTP Server

You can implement HSTS in Apache by adding the following entry in httpd.conf file or also you can add it in .htaccess

Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Nginx

To configure HSTS in Nginx, add the next entry in nginx.conf under server (SSL) directive

add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';

Microsoft IIS

Launch the IIS Manager and add the header by going to “HTTP Response Headers” for the respective site.


2. X-XSS-Protection

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.

An attacker can use XSS to send a malicious script to an unsuspecting user. The end user’s browser has no way to know that the script should not be trusted, and will execute the script. Because it thinks the script came from a trusted source, the malicious script can access any cookies, session tokens, or other sensitive information retained by the browser and used with that site. These scripts can even rewrite the content of the HTML page. For more details on the different types of XSS flaws, see: Types of Cross-Site Scripting.

below are the parameters for X-XSS header

Below are the parameters it takes

ValueDescription
0Filter disabled.
1Filter enabled. If a cross-site scripting attack is detected, in order to stop the attack, the browser will sanitize the page.
1; mode=blockFilter enabled. Rather than sanitize the page, when a XSS attack is detected, the browser will prevent rendering of the page.
1; report=http://mydomain.com/my_report_URIFilter enabled. The browser will sanitize the page and report the violation. This is a Chromium function utilizing CSP violation reports to send details to a URI of your choice.

Let’s implement 1;mode=block in the following web servers.

Apache HTTP Server

Add the following entry in httpd.conf of your Apache web server

Header set X-XSS-Protection "1; mode=block"

Nginx

Add the following in nginx.conf under http block

add_header X-XSS-Protection "1; mode=block";

Microsoft IIS

  1. Open IIS Manager
  2. Select the Site you need to enable the header for
  3. Go to “HTTP Response Headers.”
  4. Click “Add” under actions
  5. Enter name, value and click Ok

3. X-Frame-Options

X-Frame-Options response header improve the protection of web applications against Clickjacking. By implementing this header, you instruct the browser not to embed your web page in frame/iframe. This has some limitation in browser support, so you got to check before implementing it.

Below are the parameters it takes

ValueDescription
denyNo rendering within a frame.
sameoriginNo rendering if origin mismatch.
allow-from: DOMAINAllows rendering if framed by frame loaded from DOMAIN.

Let’s take a look at how to implement “sameorigin” so only your domain embeds the web page.

Apache

Add the following line in httpd.conf and restart the webserver to verify the results.

Header always append X-Frame-Options sameorigin

Nginx

Add the following in nginx.conf under server directive/block.

add_header X-Frame-Options "sameorigin";

Microsoft IIS

  1. Open IIS Manager
  2. Select the Site you need to enable the header for
  3. Go to “HTTP Response Headers.”
  4. Click “Add” under actions
  5. Enter name, value and click Ok

4. X-Content-Type-Options

Prevent MIME types security risk by adding this header to your web page’s HTTP response. Having this header instruct browser to consider files types as defined and disallow content sniffing. There is only one parameter you got to add “nosniff”.

Below are the parameters it takes

ValueDescription
nosniffWill prevent the browser from MIME-sniffing a response away from the declared content-type.

Let’s add this header to our server.

Apache

You can do this by adding the below line in httpd.conf file

Header set X-Content-Type-Options nosniff

Nginx

Add the following line in nginx.conf file under server block.

add_header X-Content-Type-Options nosniff;

Microsoft IIS

repeat the same as above to add it to IIS HTTP Response Headers field


5. HTTP Public Key Pinning

Minimize the man-in-the-middle (MITM) attacks risk by pinning certificate. This is possible with HPKP (HTTP Public Key Pinning) header.

You can pin the root certificate public key or immediate certificate. At the time of writing, HPKP currently works in Firefox and Chrome and support SHA-256 hash algorithm. Before implement HPKP please read this https://www.chromestatus.com/feature/5903385005916160

Below are the parameters it takes

ValueDescription
pin-sha256=”<sha256>”The quoted string is the Base64 encoded Subject Public Key Information (SPKI) fingerprint. It is possible to specify multiple pins for different public keys. Some browsers might allow other hashing algorithms than SHA-256 in the future.
max-age=SECONDSThe time, in seconds, that the browser should remember that this site is only to be accessed using one of the pinned keys.
includeSubDomainsIf this optional parameter is specified, this rule applies to all of the site’s subdomains as well.
report-uri=”<URL>”If this optional parameter is specified, pin validation failures are reported to the given URL.

Let’s see HPKP header example

Public-Key-Pins: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; report-uri="http://example.com/pkp-report"; max-age=10000; includeSubDomains

If you need to implement this header on your website, then head to implementation guide written by Scott Helme.


6. Content Security Policy

A Content Security Policy (CSP) requires careful tuning and precise definition of the policy. If enabled, CSP has significant impact on the way browsers render pages (e.g., inline JavaScript disabled by default and must be explicitly allowed in policy). CSP prevents a wide range of attacks, including Cross-site scripting and other cross-site injections.

All browsers don’t support CSP, so you need to verify before implementing it. There are multiple parameters possible to implement CSP, and you can refer OWASP for an idea. However, let’s go through two most used parameters. You can also use online CSP tool to easily generate policy for your website.

Below are the parameters it takes

DirectiveDescription
default-srcDefine loading policy for all resources type in case of a resource type dedicated directive is not defined (fallback).
script-srcDefine which scripts the protected resource can execute.

The following example of loading everything from the same origin and script from same origin, facebook & google analytics in various web servers.

Apache

Get the following added in httpd.conf file and restart the webserver to get effective.

Header set Content-Security-Policy "default-src 'self'; script-src 'self' *.facebook.com *.facebook.net *.google-analytics.com"

Nginx

Add the following in server block in nginx.conf file

add_header Content-Security-Policy "default-src 'self'; script-src 'self' *.facebook.com *.facebook.net *.google-analytics.com";

Microsoft IIS

do the same as above headers.


7. X-Permitted-Cross-Domain-Policies

Using Adobe products like PDF, Flash, etc.? You can implement this header to instruct the browser how to handle the requests over a cross-domain. By implementing this header, you restrict loading your site’s assets from other domain to avoid resource abuse.

Below are the parameters it takes

ValueDescription
noneNo policy files are allowed anywhere on the target server, including this master policy file.
master-onlyOnly this master policy file is allowed.
by-content-type[HTTP/HTTPS only] Only policy files served with Content-Type: text/x-cross-domain-policy are allowed.
by-ftp-filename[FTP only] Only policy files whose file names are crossdomain.xml (i.e. URLs ending in /crossdomain.xml) are allowed.
allAll policy files on this target domain are allowed.

So let’s go ahead and add this to the headers

Apache

Header set X-Permitted-Cross-Domain-Policies "none"

Nginx

add_header X-Permitted-Cross-Domain-Policies master-only;

Microsoft IIS

Same as above policies


8. Referrer Policy

The Referrer-Policy HTTP header governs which referrer information, sent in the Referer header, should be included with requests made. There are certain privacy and security benefits. However, not all the options are supported by all the browsers, so review your requirement before the implementation.

Below are the parameters it takes

ValueDescription
no-referrerThe Referer header will be omitted entirely. No referrer information is sent along with requests.
no-referrer-when-downgradeThis is the user agent’s default behavior if no policy is specified. The origin is sent as referrer to a-priori as-much-secure destination (HTTPS->HTTPS), but isn’t sent to a less secure destination (HTTPS->HTTP).
originOnly send the origin of the document as the referrer in all cases. The document https://example.com/page.html will send the referrer https://example.com/.
origin-when-cross-originSend a full URL when performing a same-origin request, but only send the origin of the document for other cases.
same-originA referrer will be sent for same-site origins, but cross-origin requests will contain no referrer information.
strict-originOnly send the origin of the document as the referrer to a-priori as-much-secure destination (HTTPS->HTTPS), but don’t send it to a less secure destination (HTTPS->HTTP).
strict-origin-when-cross-originSend a full URL when performing a same-origin request, only send the origin of the document to a-priori as-much-secure destination (HTTPS->HTTPS), and send no header to a less secure destination (HTTPS->HTTP).
unsafe-urlSend a full URL (stripped from parameters) when performing a a same-origin or cross-origin request.

Apache

You can add the following if you want to set no-referrer.

Header set Referrer-Policy "no-referrer"

Nginx

Let’s say you need to implement same-origin, so you got to add the following.

add_header Referrer-Policy same-origin;

Microsoft IIS

Do it as mentioned as above.


9. Expect-CT

The Expect-CT header is used by a server to indicate that browsers should evaluate connections to the host emitting the header for Certificate Transparency compliance. This project by Google aims to fix some of the flaws in the SSL/TLS certificate system.

Below are the parameters it takes

ValueDescription
report-uriThe optional report-uri directive indicates the URL to which the browser should report Expect-CT failures.
enforceThe optional enforce directive is a valueless directive that, if present, signals to the browser that compliance to the CT Policy should be enforced (rather than report-only) and that the browser should refuse future connections that violate its CT Policy. When both the enforce directive and report-uri directive are present, the configuration is referred to as an “enforce-and-report” configuration, signalling to the browser both that compliance to the CT Policy should be enforced and that violations should be reported.
max-ageThe max-age directive specifies the number of seconds after the reception of the Expect-CT header field during which the browser should regard the host from whom the message was received as a Known Expect-CT Host.

Apache

Let’s assume you want to enforce this policy, report, and cache for 12 hours then you need to add the following.

Header set Expect-CT 'enforce, max-age=43200, report-uri="https://reportmydomain.com/report"'

Nginx

What if you want to report and cache for 1 hour?

add_header Expect-CT 'max-age=60, report-uri="https://reportmydomain.com/report"';

Microsoft ISS

Same as above


10. Feature-Policy

The Feature-Policy header allows you to selectively enable and disable use of various browsers features and APIs. With help of this headers you define what all kind of controls are allowed or blocked for your web application.

Below are the parameters it takes

ValueDescription
accelerometerControls access to accelerometer sensors on the device.
ambient-light-sensorControls access to ambient light sensors on the device.
autoplayControls access to autoplay through play() and autoplay.
cameraControls access to video input devices.
encrypted-mediaControls whether requestMediaKeySystemAccess() is allowed.
fullscreenControls whether requestFullscreen() is allowed.
geolocationControls access to Geolocation interface.
gyroscopeControls access to gyroscope sensors on the device.
magnetometerControls access to magnetometer sensors on the device.
microphoneControls access to audio input devices.
midiControls access to requestMIDIAccess() method.
paymentControls access to PaymentRequest interface.
picture-in-pictureControls access to Picture in Picture.
speakerControls access to audio output devices.
usbControls access to USB devices.
vibrateControls access to vibrate() method.
vrControls access to VR displays.

Apache

Let’s say you need to disable the full screen feature and to do so; you can add the following in httpd.conf or apache2.conf.

Header always set Feature-Policy "fullscreen 'none' "

It is also possible to add multiple features in a single line.

Header always set Feature-Policy "fullscreen 'none'; microphone 'none'"

Nginx

Let’s take another example – disable geolocation, camera and speaker feature.

add_header Feature-Policy "geolocation 'none'; camera 'none'; speaker 'none';";

11. Cookies with HttpOnly and secure Flags

You can mitigate most common XSS attacks using HttpOnly and Secure flag with your cookie. Without having HttpOnly and Secure flag in the HTTP response header, it is possible to steal or manipulate web application session and cookies.

t’s better to manage this within the application code. However, due to developer’s unawareness, it comes to Web Server administrators.

Apache

Ensure you have mod_headers.so enabled in Apache HTTP server. Add following entry in httpd.conf

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

Above entry will add HttpOnly & Secure irrespective to it is already set or not. You can use below code to set HttpOnly;Secure only if it is missing.

Header always edit Set-Cookie "(?i)^((?:(?!;\s?HttpOnly).)+)$" "$1; HttpOnly"
Header always edit Set-Cookie "(?i)^((?:(?!;\s?secure).)+)$" "$1; secure"

12. Same-Site Cookie Attribute

Additionally you can use the Same-Site Cookie Attribute to Prevent CSRF Attacks. Thanks to a new cookie attribute, that Google Chrome started supporting on the 29th of March, and other the popular browsers followed, there is now a solution. It is called the Same-Site cookie attribute.

Setting a Same-Site attribute to a cookie is quite simple. It consists of adding just one instruction to the cookie. Simply adding ‘SameSite=Lax’ or ‘SameSite=Strict’ is enough!

Below are the parameters it takes

Value Description
LaxIn lax mode, some cross-site usage is allowed. Specifically if the request is a GET request and the request is top-level. Top-level means that the URL in the address bar changes because of this navigation. This is not the case for iframes, images or XMLHttpRequests.
strictIn the strict mode, the cookie is withheld with any cross-site usage. Even when the user follows a link to another website the cookie is not sent.

SameSite=None: Deprecate and remove the use of cookies with the SameSite=None attribute but without the Secure attribute. Any cookie that requests SameSite=None but is not marked Secure will be rejected.

Apache

In order to set this in apache you can add following in httpd.conf/virtualhost/.htaccess

Header always edit Set-Cookie (.*) "$1; SameSite=Lax"

Note : if you are adding these headers to the Apache / Nginx or Microsoft IIS configs then don’t forget to restart the web server.

If you are using Apache web server then you can add these headers to the .htaccess file also. below is a snippet for adding all above headers to htaccess.

<ifModule mod_headers.c>
Header always edit Set-Cookie (.*) "$1; SameSite=Lax"
Header always edit Set-Cookie "(?i)^((?:(?!;\s?HttpOnly).)+)$" "$1; HttpOnly"
Header always edit Set-Cookie "(?i)^((?:(?!;\s?secure).)+)$" "$1; secure"
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always append X-Frame-Options sameorigin
Header always set X-Content-Type-Options nosniff
Header set Content-Security-Policy "default-src 'self'; script-src 'self' *.facebook.net *.facebook.com *.onesignal.com *.google-analytics.com 'unsafe-inline';"
Header always set X-Permitted-Cross-Domain-Policies "none"
Header always set Referrer-Policy "no-referrer-when-downgrade"
Header always set Feature-Policy "fullscreen 'none'; microphone 'none'"
</ifModule>

Securing a website is challenging, and I hope by implementing the above headers, you add a layer of security.

0 0 vote
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments