L7 Hardening: Security Headers

There are quite some directives at hand that can be added to your webserver configuration to achieve hardening against many attacks. Most websites – even those that really should – do not care, and thus receive a grade F when being checked by schd.io.

It is pretty straightforward to change that completely. In nginx 1.6.2, just edit the site’s config file and insert:

add_header Strict-Transport-Security "max-age=31536000";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Xss-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

The equivalent in nginx 1.8+ would be:

add_header Strict-Transport-Security "max-age=31536000";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Xss-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;

This already gives us a grade C, but there is another powerful mechanism: the content security policy (CSP) is restricting the abilities of the browser to those predefined by you, especially only allowing certain servers to serve certain elements of the site’s content in the first place.

So lets take a closer look into this basic rule:

add_header Content-Security-Policy "default-src 'self'; connect-src 'self'; img-src 'self'; script-src 'self' ; style-src 'self' 'unsafe-inline' ";

This is restrictive and works only on static websites not involving any other sources for images, scripts or fonts.

As in most if not all cases when dealing w/ security, all this also involves the well known, eternal conflict: security vs. usability.

For example, webmail applications and underlying plugins often include inline javascript and thus need a bit less of restrictions expressed by

add_header Content-Security-Policy "default-src 'self'; connect-src 'self'; img-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' ";

WordPress for example would require restrictions similar to

add_header Content-Security-Policy "default-src 'self'; connect-src 'self'; img-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:";

The most efficient way to implement a valid CSP for your website and/or application is to use the debugging shortcut F12 in the browser of your choice and check the console for relevant messages while at the same time creating parameters for your CSP that fit the actual operational needs.

Leave a Reply