Web application security is hard to implement and harder still to maintain. The application layer is also the top attack vector for data loss, via such well-known vulnerabilities as SQL injection. Needless to say, we infosec practitioners are always looking for an application security “easy button.” Part of the solution is staring us right in the eyes, yet we have been slow to leverage HTTP response headers.
With that in mind, the revelations of Scott Helme’s recent survey of the top one million web sites came as a huge shock. Security-centric HTTP response headers are relatively easy to insert and provide a range of robust protections against attacks such as cross-site request forgery (CSRF), cross-site scripting (XSS), and clickjacking. Yet, the use of these standard HTTP security headers barely cracks the single digits, much less the double digits. Helme is not merely chastising us for our inability to deploy these application security measures, he also provides helpful guidance on implementing them in an earlier post on his blog.
Inserting a header in the server’s HTTP response is typically transparent to the end-user and the application, and has the effect of strengthening the weakest point of any web application transaction—the browser.
The browser has two chief disadvantages when it comes to security:
- The browser must be compatible with every web site on the Internet
- The browser is subject to the decisions of the human driving it
The security-centric HTTP headers available empower the browser to make smarter security decisions for the human user.
Let’s dig into a few of my HTTP headers (percentage of sites in the Alexa top one million):
- HTTP Strict Transport Security (1.2%)
Strict Transport Security leaps immediately to the front since the HSTS header is mandatory to achieve an A+ rating with Qualys’ SSL Labs. Upon receiving the HSTS header, the browser will refuse to load the specified domain over clear-text HTTP. Set the HSTS header for a long duration (6 months or greater), and only insert it via an already-established HTTPS session. Also, insert the HSTS header using the server configuration methods Helme covers, or by a proxy such as an ADC or a WAF device.
- HTTPS Permanent Redirect (6.7%)
Related to the final point about HSTS above, but not strictly a header, it is important to pin all traffic to HTTPS. By sending a 301 (permanent) redirect to any browser attempting to reach the site via clear-text HTTP, we ensure encryption for all meaningful transactions. Encrypting HTTP transactions with TLS, the successor to SSL, makes it much more difficult to intercept and manipulate any of the security-centric HTTP headers we insert.
- HTTP Public Key Pinning (0.02%)
Also related to TLS encryption, HPKP headers ensure the integrity of the TLS handshake. HPKP headers are also the least common of all the security-centric headers in Helme’s survey. Moxie Marlinspike has long covered the problem of authenticity in the TLS transaction, and has said the Certificate Authority system is utterly broken. The notion of a root trust in a Certificate Authority is utterly flawed, especially in the wake of the DigiNotar and Comodo compromises of the last few years. However, there are ways to bolster the verification of certificate authenticity beyond chains of trust to certificate authorities (CAs). public key pinning ensures that the browser has a valid copy of the certificate to compare to any certificate presented by a server. So, even the case of DNS poisoning, a compromised CA, or some other vector for a man-in-the-middle of the encrypted connection, the browser can compare and verify the pinned certificate with the certificate presented in the handshake. For more details, Yahoo penetration tester, Stuart Larsen, has a great talk on the topic of HPKP.
- Content Security Policy (~2%)
Content security policy (CSP) headers come in a few different flavors, owing to a long time as an “experimental” header (XCSP and XWCSP). At BlackHat 2013, Qualys researchers Mike Shema and Vaagn Toukharian made a strong proposal for leveraging CSP as a mechanism for fighting CSRF. Cross-site request forgery generally requires an initial XSS attack vector along with some phishing to be successful, but the complicated nature of executing a CSRF attack is rewarded with authenticated access to the vulnerable web application. CSP headers fight this by instructing browsers where and how it can legitimately load content for the page. A nice feature of CSP headers is the “report only” option, which enables a slow-ramp to find out what origins the browser attempts load. Reviewing the reports can avail us of what “normal” looks like as well as alert us of abnormal attempts without blocking and causing a false positive.
- X-Frame-Options (5.9%)
The XFO header is more widely deployed than most, because of the ease of deployment and the strength in mitigating clickjacking attacks, principally discovered (and named) by Jeremiah Grossman and RSnake of WhiteHat Security back in 2009. Clickjacking is particularly nasty since it causes a user to click on a transparent frame in the browser during their normal interactions with the web application. The most critical threat would be framing the login form so that clickjackers can intercept credentials. XFO headers instruct the browser when and if to allow any framing. The only catch here is that some sites may still(!) be using frames, which would make XFO headers somewhat untenable. That being said, I doubt that 94.1% of the top one million web sites are still using frames for any legitimate, intended purpose. We can do better.
We only covered the top five HTTP response modifications that enable better application security.
However, the benefits of implementing them are significant, and include:
- Ensures the browser to only load content via encrypted connections
- Forces the browser to verify the authenticity of the certificate presented
- Prevents most XSS, CSRF, and other common phishing and malware vectors
- Prevents most methods of clickjacking
The net result is improved application security without the need for signature-based detections, application code changes, or changes in user experience (UX). Due to application dependencies or operational obstacles, we may not be able to implement Helme’s detailed instructions for modifying common application servers like IIS and nginx. However, we still have the opportunity to implement these security measures via common proxies such as the application delivery controller (ADC), load-balancer, or web application firewall (WAF). Anything we can do to strengthen the weakest link in application security, the browser, is worth it. And according to Helme’s survey, 99% of us are leaving that security value on the table. Let’s get to work.