Introduction to HTTP Response Headers for Security
Hyper Text Transfer Protocol (HTTP) is a stateless protocol. The implication of this is, at the protocol level there is no record of what happened in the past. The original purpose of the HTTP protocol was to transfer files and see interconnected information. The World Wide Web has evolved into a much bigger and more complex system that the original architects didn't even imagine. It is the biggest open market place in the history of the world.
Most of the Web applications are usually front-ends for databases and contain user-specific data, and use 'sessions' to maintain their state. A session is created once a user is authenticated by entering a username and password. This type of authentication is called form-based authentication and this is true for HTTP authentication as well. Once the authentication is successful, the user can now browse the Web application seamlessly.
11 courses, 8+ hours of training
11 courses, 8+ hours of training
Secure Cookies
One of the most popular ways a session is maintained is by sending a Set-Cookie HTTP response header to the browser. Once this cookie has been set, the only way a server will know which client/browser it is talking to is when the client/browser sends the same cookie value with each and every request made to the server. This is sent as part of the HTTP Request Header. This could be a session cookie created by PHP, ASP.net, Java Struts, HTTP basic authentication, Windows domain token, etc.
Browsers have their own security model and they ensure that only the Website setting this cookie is able to read it. Obviously a cookie is little more complicated than that but you get the idea. Also this type of cookie is sometimes referred to as a session cookie. We know that, if someone is able to inject JavaScript which wasn't part of the original Webpage, it results in what is called Cross Site Scripting (XSS). Therefore a session hijacker just needs to steal the cookie value to hijack a session and impersonate as an authenticated user. For all intents and purposes the session cookie value represents the user on the server.
- Session Cookie can be stolen due to XSS
In an ideal world there will be no Web application vulnerabilities and we will all be safe on the Internet. But currently, according to the statistics given by the Open Web Application Security Project (OWASP), XSS is the most exploited vulnerability on the Web. The Open Web Application Security Project lists XSS as the 2nd most risky vulnerability as part of its Top 10 critical risks facing Web applications. It doesn't matter if the Website is using SSL/TLS. This is because the encryption provided by them is on a layer below.
To overcome this massive flaw a new keyword was introduced by the Microsoft's IE team HTTPOnly to the Set-Cookie. Any supporting browser will not share the value of a HTTPOnly cookie with the JavaScript executing in the browser. Adding the Secure keyword will ensure that this cookie will only go over the wire, when the browser has a secure HTTP connection with the server.
Set-Cookie: GALX=<big random value >; expires=<time stamp> GMT; path=/;Secure;HttpOnly
As the Web has evolved from simple Websites to complex Web applications, with data and user interface mashed up for amazing user experiences, the people who are entrusted with making sure that users remain secure (namely browser vendors) have introduced and added additional HTTP response headers for security. Anyone responsible for the programming Web applications should be aware of these headers and how to use them properly. Also, testers looking at the security of Web applications should be checking to see if these headers are present and being used in a proper manner.
Using the Header to Prevent XSS
Microsoft IE8 started shipping with a built-in client side XSS prevention tool. By default, it is enabled for all users, but Website owners who wish to disable this for various reasons can send the following HTTP response header.
X-XSS-Protection: 0
Currently gmail.com sends this as:
X-XSS-Protection: 1; mode=block
The one big drawback of this header is that the filter only works against reflective XSS, and it has been bypassed on a number of occasions. Although this may not be the best solution, in the interest of in-depth defencethis should sent as part of the response.
This keyword mode was added later to completely block a Web page being rendered when XSS is detected, rather than the filter trying to sanitize the page. This is definitely a welcome addition for everyone.
ClickjackingClickjacking is one of the more under rated attacks facing modern Web applications. This is one reason it doesn't find a mention in the OWASP Top 10 list so far. I predict that this attack will be a feature in the next version of the Top 10 and more developers and testers will become aware of how devastating its effects can be. Rather than spend time explaining exactly how clickjacking works, I would much rather talk about its mitigation techniques for developers. But, the problem is I can't. That's right; there are no effective mitigation techniques against clickjacking that can be programmed as part of the Web application logic. The attack in its simplest form, loads an invisible iframe of the application being attacked in such a way that, whatever user input is being sent, is sent to this application. The only mitigation is to ensure that the sensitive parts of the Web application (mostly everything) shouldn't be allowed to be framed.
You can pass two options either completely denying framing of a Web page:
X-Frame-Options: DENY
Or allowing framing from only those Web pages which originated from the same place.
X-Frame-Options: SAMEORIGIN
Keep in mind that the response HTTP header only works if the browser is able to understand what needs to be done. Therefore not all browsers support this header. Namely IE6 and IE7 don't know about this header. So if a Web site has many users still using older obsolete browsers, they are at a risk from clickjacking.
Strict-Transport-Security
This is a HTTP response header which tells the browser that it should be loaded over HTTPS. This is required to avoid an attack as mentioned by Moxie Marlinspike called SSL Strip. In this attack even one request sent over HTTP allows the attacker to spoof the HTTPS requests to the Website.
Strict-Transport-Security: max-age=expireTime [; includeSubdomains]
This is useful if you insist on accessing your bank Website while using free public WiFi. The header can't take care of the first request made by the browser which might be to load the HTTP version. Typically Websites set an expiry time of 100 days to ensure that the header isn't expiring.
Strict-Transport-Security: max-age=8640000
This header is only supported by Firefox, Chrome and Opera. Another drawback is that if this header is set then the Website will not load up for self-signed certificates. If the MITM attack is already underway and the site hasn't been requested there is always a chance that the attacker will remove the header. There is no solution for this problem except what Chrome is doing currently. Chrome ships with a list of STS enabled Websites. In a way you can't load sites like PayPal, encrypted.google.com, etc. using HTTP with Chrome anymore. Since such Websites will not even load with non-secure content there is no chance of attacks like sidejacking. Some of you might recall sidejacking was made popular by a Firefox extension called Firesheep.
Content Sniffing Attacks
Internet Explorer could be fooled into believing a HTML page was a PNG image while doing an upload and that could become an XSS vector.
The correct way to use the header is:
X-Content-Type-Options: nosniff
This informs the browser that the any content type that is not explicitly specified shouldn't be guessed. IE8 also defaults to text/plain when it is doesn't receive the content type from the server. This is used only in IE and Google Chrome when downloading extensions.
- HTTP response headers for security being used at Google
Content Security Policy
Rather than use the patchwork of different HTTP response headers for increasing security of its users, Mozilla decided to tackle the problem slightly differently. They created what is called the Content Security Policy (CSP). Recognising that more and more Websites are pulling active content from various domains, the Content Security Policy allows the Website owner to whitelist domains other than itself. This does mean that the onus on protecting those domains is with the Website owner.
There are many policy directives that can be set and the best reference for this is "Using the Content Security Policy" document hosted on the Mozilla Developer Network wiki.
Sample Policy
X-Content-Security-Policy:
allow 'self';
img-src *;
object-src media1.com media2.com;
script-src userscripts.example.com;
allow https://payments.example.com
This policy defines that all scripts from the same domain are allowed. The image sources can point to any domain (this is a weakness) and objects like flash etc. can be loaded from specified domains. Additionally the payments subdomain can only be loaded over SSL/TLS.
In a way Mozilla has incorporated the XSS prevention, STS as part of the CSP. This seems to me a more elegant and sustainable solution in the longer term. Once the Content Security Policy is more widely adapted, Website owners will get a more granular control over how the end users will be able to use their Web applications. In turn, it will also mean that Web clients not supporting these new headers will either have to be rewritten or they might be locked out from using certain Websites.
Website users are facing newer and more dangerous threats nowadays. These range from clickjacking to JSON injections to likejacking. Companies such as Google, Mozilla, Microsoft and others have started adding these new HTTP response headers to counter some of the advanced attacks against their Website users. As we saw earlier, some of the attacks are because of how HTTP is and therefore are impossible to defend against by the Web applications alone. It requires a co-ordinated effort between the HTTP, server vendors and the browser vendors to make the Web safer for its users.
Some of these new attacks aren't that well understood by the Web application developers and hence they aren't using the new HTTP response headers meant for security that is present in the newer browsers. This is either due to ignorance or there being no business case to update in order to continue supporting older insecure browser versions of Internet Explorer.
- Content Security Policy being used
Conclusion
Modern Web applications require modern and upgraded defences. As the Web applications have become more sophisticated, so have the Web browsers. This in turn has spurned newer attacks and consequently defences. We looked at some of the new HTTP response headers being used to protect Web users from various kinds of attacks.
- Set-Cookie Secure HttpOnly
- X-Frame-Options
- X-XSS-Protection
- X-Content-Type-Options
- Strict-Transport-Security
- X-Content-Security-Policy