User-targeted attacks, such as XSS, often involve manipulating the server or browser into behaving in a manner not originally intended. While this has always been a serious risk, new HTML5 technologies enhance browser capabilities enough to make client-side attacks an increasingly inviting attack vector.
For a web developer, protecting the client has traditionally been limited to preventing client-side injection and browser manipulation. Beyond that, there was not much more that could be done other than helping users to make smart security decisions. But with the new features of HTML5 comes new ways to improve client-side security through security headers.
Security headers are HTTP response headers that direct the browser’s behavior to enhance a web site’s security. To prevent attackers from manipulating browser behavior, security headers allow you to be specific about your intentions for content served from your web site.
Some of these header specifications are fairly new or browser-specific and they are not universally implemented across all browsers, but there is enough support that now is the time to start implementing these in some form.
If you aren’t already aware of the various security headers available, I thought I would do a quick summary:
Content Security Policy (CSP)
CSP is a least privilege approach to security that uses the
Content-Security-Policy, X-Content-Security-Policy, or
X-WebKit-CSP headers (depending on your browser) to define exactly which resources the browser is allowed to load for any particular page and from where they can be loaded. So if you want a certain document to only be able to load scripts from a specific server you can now specify that through the CSP header. CSP currently allows you to set restrictions for loading scripts, objects, styles, images, media, frames, and fonts. By default, CSP also blocks
eval(), inline scripts, inline CSS styles, and data URIs. It further allows you to provide a reporting URL to help identity possible emerging threats which is especially helpful for DOM-Based XSS attacks that are normally difficult to detect.
At this point, CSP specifications vary between browsers and support in mobile browsers is somewhat limited. On top of that, many web sites use inline code and make use of the
eval() function so initially full implementation is likely not possible. Still, even the most basic CSP implementation can cripple a large number of client-side attack vectors and is well worth the effort to implement.
In short, CSP is already a powerful tool for limiting client-side attacks and it looks to be an even more promising technique as the specification evolves.
Here is a demo page that shows how CSP can affect page elements (hint: use your browser’s developer panel to view messages about blocked elements).
Some tips for using CSP:
- Use SSL to prevent tampering of CSP headers.
- Set very specific origins for each type of resource rather than using the * wildcard.
- The browser will fall back to a default source if none is provided so use the default-src directive to set a blanket policy.
- When using a reporting URL, make sure you take precautions to prevent that from introducing new vulnerabilities.
Other useful CSP Resources:
Cross-Origin Resource Sharing (CORS)
CORS doesn’t directly increase security, it actually reduces it. But it allows you to do so in a controlled and granular manner to limit exposure to attack. Normally same-origin policy only allows a script to access resources from the same host. For those times when you need to access resources from other hosts, you can limit access for your specific needs. The CORS-related headers are:
Tips for using CORS:
- Never allow GET or OPTIONS requests to modify data.
- Use the Access-Control-Allow-Origin headers as needed on a per-resource basis, rather than for the entire domain.
- Only use Access-Control-Allow-Origin: * for publicly-accessible static resources that do not include sensitive information or modify data.
HTTP Strict Transport Security (HSTS)
HSTS uses the Strict-Transport-Security header to tell the web browser to only server resources from your site using HTTPS. Once specified, the HSTS header will cause the browser to upgrade all HTTP requests to HTTPS. It also prevents users from overriding invalid certificate errors for your site.
Tips for using HSTS:
- The browser only needs to see the header once so you generally only need to set it for documents, not for the resources loaded by those documents.
- Because the browser will only honor HSTS headers delivered via HTTPS, you must still configure your site to redirect all resources to HTTPS so the browser gets the HSTS header.
X-Frame-Options header allows you to direct browsers not to embed a document in a frame or to only embed it from documents of the same origin. The purpose of this is to reduce exposure to clickjacking attacks. Although this header does not guarantee your content will never appear in a frame on all clients, all major web browsers will honor this and browsers are the primary mechanism for clickjacking attacks. Most web sites should implement this at least for documents of the same origin.
X-Frame-Options header provides for two options: Deny, to block all frame embeds, or SameOrigin, to only allow the page to embed in frames from the same server.
Internet Explorer provides support for additional security headers not found in other web browsers. Although these protections only protect a portion of your user base, even a small decrease of attack surface is worth the effort.
One IE-specific feature, the
X-Content-Type-Options: nosniff header prevents the browser from improperly identifying MIME types. For example, it will not load a script unless the server specifically identifies it as a script through the Content-Type response header.
This header allows a web server to specify that a document should never be loaded in the browser and must be saved locally to view. This helps to prevent the browser from loading scripts and other potentially dangerous resources.
X-XSS-Protection header, allows you to control behavior of the IE XSS Filter which protects from a number of reflective XSS attacks. Normally XSS protection is enabled by default in Internet Explorer, but this header provides you with two additional options to control this filter.
First, if the filter causes problems with your web site and your site is already well-tested for XSS vulnerabilities, you can disable the filter using this header:
Second, you can make the filter more aggressive by completely blocking a page when XSS is detected rather than trying to simple filter out the attack. You can enable this with the header:
X-XSS-Protection: 1; mode=block
The best thing about most of these security headers is that you generally do not need a full implementation to benefit from some of their protections. Although the ideal solution would be to coordinate security header implement between developers and web administrators, developers can implement many of these headers on a limited basis via code. Even if you are unable to implement security headers right now, it is important for developers to be aware of these features to lay the groundwork for future implementation. Moving away from inline scripts and styles, for example, is a major task that must be undertaken to prepare full CSP deployment. Start making those changes now because these security headers will make eventually play a major role in client security.