Essential HTTP security headers

Enhance the overall security of a website or application and prevent the exploitation of potential vulnerabilities.

Essential HTTP security headers

I received a security audit report from a client a few weeks ago, they were very worried as according to the report their website had plenty of high & medium severity vulnerabilities.

I quickly realized that most of the reported issues are due to missing or miss configured HTTP headers. It was a good opportunity to review and summarize the security headers any website or web app should use.

The HTTP headers can be configured on the server to enhance the overall security of the website or web application, adding them won't literally make the site or app more secure, but will prevent the exploitation of potential vulnerabilities.

There are 2 types of HTTP headers we have to pay attention to:

1) The headers that protect against attacks

  • X-Frame-Options
  • X-Content-Type-Options
  • X-XSS-Protection
  • Content-Security-Policy
  • Strict-Transport-Security
  • Access-Control-Allow-Origin

2) The headers that leak information

  • Server
  • X-Powered-By

1) The headers that protect against attacks

These headers can be quite easily set using .htaccess, just make sure you have Apache's mod_headers enabled.

X-Frame-Options

Protects against clickjacking.

If a malicious website can embed your site as an iframe it may allow attackers to invoke unintended actions by the user with clickjacking.

To prevent your website from being embedded in an iframe set the X-Frame-Options to DENY.

Header always append X-Frame-Options DENY

X-Content-Type-Options

Protects against MIME sniffing.

When a malicious HTML document is served from your domain (for example, if an image uploaded to a photo service contains valid HTML markup), some browsers will treat it as an active document and allow it to execute scripts in the context of the application.

This is known as content sniffing, the automatic detection of the content type, we need to tell browsers to not sniff content.

Header set X-Content-Type-Options nosniff

X-XSS-Protection (deprecated)

Protects against cross-site scripting (XSS).

The X-XSS-Protection header has been deprecated by modern browsers and its use can introduce additional security issues on the client-side. (Better use Content-Security-Policy instead).

It is recommended to set the header as X-XSS-Protection: 0 in order to disable the XSS Auditor, and not allow it to take the default behavior of the browser handling the response.

Header set X-XSS-Protection 0

Content-Security-Policy (CSP)

Protects against cross-site scripting (XSS), clickjacking and HTML injection attacks.

The Content-Security-Policy provides an added layer to mitigate XSS attacks by restricting which scripts can be executed by the page. It's probably the most important header, but also the most tedious to configure.

Please note there's no one-size-fits-all CSP, you have to generate CSP policy specific to the resources loaded by your website.

Header set Content-Security-Policy "default-src * data: 'unsafe-inline' 'unsafe-eval'"

Strict-Transport-Security (HSTS)

Protects against man-in-the-middle attacks.

HTTP Strict Transport Security instructs the browser to access the webserver over HTTPS only.

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

Learn more about HSTS here.

Access-Control-Allow-Origin

Protects against cross-site request forgery (CSRF) attacks.

This is a CORS (Cross-Origin Resource Sharing) header. By default, modern browsers enforce the same-origin policy to prevent a web page from accessing cross-origin resources.

Many developers use a wildcard Access-Control-Allow-Origin header which explicitly opens up cross-origin requests from the attacker’s origin.

Don't set this header unless you need to allow AJAX requests from external origins, if so, be specific.

 Header set Access-Control-Allow-Origin "https://mysite.com"

.htaccess

Enable the headers that protect against attacks using these directives:

<IfModule mod_headers.c>
    # Security Headers
    Header set X-XSS-Protection 0
    Header always append X-Frame-Options DENY
    Header set X-Content-Type-Options nosniff
    Header set Strict-Transport-Security "max-age=10886400; includeSubDomains; preload"
    #Header set Content-Security-Policy "default-src * data: 'unsafe-inline' 'unsafe-eval'"
</IfModule>

2) The headers that leak information

To update these headers you'll likely need to get your hands dirty with server configuration files.

Server

This header contains information about the software used by the backend server that handles the request.

Screenshot 2021-08-29 at 13.10.21.png

An overly-detailed Server value might make it easier for attackers to exploit known security holes.

Update the server settings to show the least info possible.

In httpd.conf update ServerTokens to "Prod"

ServerTokens Prod

Or, if you have WHM access, go to Service Configuration > Apache Configuration > Global Configuration and set Server Tokens to "Product Only".

X-Powered-By

This header reveals information about the technology used in an application and can be a valuable hint for hackers who can exploit the security weaknesses of the technology, especially when using outdated software.

Screenshot 2021-08-29 at 13.06.29.png

It's highly recommended to remove this header.

In php.ini set:

expose_php = Off

Or, if you have WHM access, go to Software > MultiPHP INI Editor > Editor Mode tab and look for the expose_php directive and set it to "Off".