Whether we like it or not, HTTP is the de facto application transport protocol of the modern age. We use it everywhere. It’s as ubiquitous as IP and TCP, and serves much the same purpose. Its only goal is to transport the digital gold of today’s business: data.
Whether that data is JSON or XML or URL-encoded is irrelevant. It is HTTP that apps and devices use to communicate with servers and services in the cloud and on-premises in the data center.
Unlike IP and TCP, however, HTTP is a text-based protocol. It is highly flexible and can transport a variety of data – from binary to text. We use it to stream data, to retrieve data, and to collect data.
Attackers use it liberally because, as mentioned, it’s a text-based protocol with fairly lax rules regarding extensions of the headers that specify everything from what action the client expects the server to take (the HTTP ‘method’) to the resource being requested (the URI) to what kind of content can be accepted (the ‘Accept’ headers). These rules are lax to enable extensibility.
For example, the X-Forwarded-For header was introduced as a means to ensure developers were able to ‘see’ the original client IP address. In certain architectures – particularly those in which intermediaries act as full-proxies – this information can be lost. Some applications need that data, and thus developers (and networking vendors) extended the HTTP protocol by introducing a custom header. This is part of the HTTP specification; it allows for innovation and the introduction of new behavior and capabilities without requiring changes to the protocol. It’s a good thing.
Except when it isn’t.
It isn’t a good thing when this flexibility is not taken into account by developers of the servers supporting HTTP or by those responsible for securing applications that rely on HTTP.
Here’s a small sampling of CVEs related to HTTP that exploit a vulnerability in HTTP headers:
|Remote access / execution
|Data leak / DoS
Honestly, a search through known CVEs for HTTP vulnerabilities returns an excessively long list (and includes a wide variety of vendors and software) that I am not going to duplicate here. A significant portion of those are generally triggered through the abuse of an HTTP header.
A note on Optionsbleed
Optionsbleed is one of the most recent vulnerabilities. I call it out because it exists in Apache HTTP itself. Given that Netcraft currently estimates Apache runs on “more than 2.8 million web-facing computers currently run various versions and derivatives of the Apache httpd, giving it a 42.8% share of all web-facing computers”, vulnerabilities in it become significant risk. Luckily, this particular vulnerability is triggered via an HTTP header but also requires the existence of a misconfigured Limits directive within the .htaccess file. This post from Sophos provides a great overview of the gory technical details if you’re so inclined. The TL;DR is that if the misconfiguration exists, an attacker can exploit a vulnerability in Apache through the HTTP method header and (so it seems) force the server to “bleed” out data belonging to, well, someone else.
Now, I said all that, so I could say this: app security is a stack. That stack includes the platforms (and thus protocols) upon which applications rely. Like HTTP.
We need to do a better job protecting HTTP from being abused to compromise security. Whether it’s a data leak or a DoS or remote access is not the point. They are all bad impacts. We need to do a better job of recognizing that HTTP is an increasingly popular attack surface. That it is text-based means that the entire interaction between a client and the HTTP service should be classified as user input.
That should, in turn, encourage a security strategy that includes sanitization of that input. Yes, that means protocol enforcement and scrubbing upstream (before it gets to a potentially vulnerable HTTP server).
That means a web application firewall or programmable proxy should live in front of any public-facing HTTP service and actively engage in scrubbing incoming HTTP requests.
The reason for this is based on the way that web platforms process HTTP headers, which is to say before the request is ever seen by a developer. Thus, we can’t necessarily point at developers and blame insecure coding practices for platform-level vulnerabilities.
Patching is the ultimate solution, of course. Provided you (1) hear about the vulnerability day zero, (2) a patch is made available day zero, and (3) you are comfortable deploying a potentially untested patch to production systems.
You need to patch, don’t get me wrong, but there is a gap between disclosure, discovery, availability, and application. In that gap lies risk; the risk that a very easy to exploit vulnerability will be used against you.
The penultimate solution is to ensure there is a system (a platform) in place on which you can deploy immediate remediation solutions such as scripts or signature-based scanning to prevent exploitation while you prepare to patch.
Scrubbing inbound data and enforcing protocol correctness should be part and parcel of any corporate security policy.
HTTP is increasingly risky, but it is also manageable if you remember that app security is a stack and then move to put in place protections at each layer of that stack.