Web cache poisoning just got real: How to fling evil code at victims
Cache me outside, how 'bout dah?
BSides Manchester Websites can be hijacked to turn their caches into exploit delivery systems.
James Kettle of Portswigger, the biz behind Burp Suite, has developed techniques to go beyond previous cache poisoning.
Caching speeds up webpage loads by reducing latency while also reducing the load on application server. Some organizations host their own cache using software like Varnish, and others opt to rely on a Content Delivery Network such as Cloudflare, with caches scattered across geographical locations. Also, some popular web applications and frameworks like Drupal – a popular content management system – have a built-in cache.
Web cache poisoning is geared towards sending a request that causes a harmful response that then gets saved in the cache and served to other users.
Kettle's research focused on looking at how it might be possible to poison caches using unkeyed inputs1 such as HTTP headers. Other, likely less fruitful trickery, such as request smuggling [PDF] might also be possible, as Kettle is careful to note.
In spite of its "fearsome reputation", cache poisoning is often very easy to exploit, Kettle discovered when he began experimenting with the attack, exclusively targeting websites with researcher-friendly policies.
The researcher said he was able to compromise Mozilla’s infrastructure and partially hijack a notorious Firefox feature2, related to a badly thought-through add-on designed to promote hacking-themed show Mr Robot. The approach theoretically would have allowed Kettle to co-opt millions of Firefox browsers as a low-fat botnet.
The potential for mischief was somewhat curtailed by controls that meant only code signed by Mozilla could be pushed in this way but it nonetheless posed the potential to cause problems, as Kettle explained.
"The recipes used by Firefox were signed so I couldn't just install a malicious add-on and get full code execution, but I could direct tens of millions of genuine users to a URL of my choice," he said. "Aside from the obvious DDoS usage, this would be extremely serious if combined with an appropriate memory corruption vulnerability.
"Also, some backend Mozilla systems use unsigned recipes, which could potentially be used to obtain a foothold deep inside their infrastructure and perhaps obtain the recipe-signing key. Furthermore, I could replay old recipes of my choice which could potentially force mass installation of an old known-vulnerable extension, or the unexpected return of Mr Robot."
Kettle reported the issue to Mozilla and it patched its infrastructure in under 24 hours but there was some disagreement about the severity of the problem, so the exploit only attracted a bug bounty of $1,000.
The researcher discovered problems in another direction after he expanded the header wordlist by downloading and scouring the top 20,000 PHP projects on GitHub for header names.
"This revealed the headers X-Original-URL and X-Rewrite-URL which override the request's path," Kettle explained. "I first noticed them affecting targets running Drupal, and digging through Drupal's code revealed that the support for this header comes from the popular PHP framework Symfony, which in turn took the code from Zend."
He added: "The end result is that a huge number of PHP applications unwittingly support these headers."
These headers are "great for bypassing WAFs and security rules" as well as offering an avenue for cache poisoning, according to Kettle. If an application uses a cache, these headers can be abused to confuse it into serving up incorrect pages.
Unity through strife
One attack (which Kettle christened as "local route poisoning") allows someone to replace a path with another path. The end result is that after sending this request, anyone who tries to access the Unity for Education webpage is liable to get a bit of a surprise.
Other related security flaws create a means for hackers to override the query string. This, when combine with Drupal's open redirect, created "building blocks" for hacker exploitation.
"We can combine the parameter override attack with the open redirect to persistently hijack any redirect," Kettle explained, adding that pages on pinterest.com are among sites that are vulnerable.
Nested cache poisoning, a two-stage attack, was also possible. "If the site uses an external cache (like virtually all high-traffic Drupal sites), we can use the internal cache to poison the external cache, and in the process convert any response into a redirection," Kettle explained.
The practical upshot, as demonstrated by Kettle, is that clicking "Download installer" on unity.com would download some opportunistic malware from evil.net.
This vulnerability was disclosed to Drupal, Symfony, and Zend in May. A security update is now available, and should be installed.
Kettle cited Mozilla and Drupal as particular examples during a well-received presentation at BSides Manchester in England on Thursday, which he delivered days after unveiling his research at Black Hat in Las Vegas, USA. Other projects also had cache weaknesses, and the response from them was mixed, he said in this blog post:
The response from my targets was mixed; Unity patched everything swiftly and rewarded well, Mozilla at least patched quickly, and others including data.gov and Ghost did nothing for months and only patched due to the threat of imminent publication.
Many of these case studies exploit secondary vulnerabilities such as XSS in the unkeyed input, and it's important to remember that without cache poisoning, such vulnerabilities are useless as there's no reliable way to force another user to send a custom header on a cross-domain request. That's probably why they were so easy to find.
Here's a video of his presentation at Bsides with more detail, if you're interested:
How to protect yourself
Kettle said that websites should either test to make sure they are not vulnerable or restrict the use of caching in order to avoid potential problems.
"The most robust defence against cache poisoning is to disable caching," Kettle advised. "This is plainly unrealistic advice for some, but I suspect that quite a few websites start using a service like Cloudflare for DDoS protection or easy SSL, and end up vulnerable to cache poisoning simply because caching is enabled by default."
"Restricting caching to purely static responses is also effective, provided you're sufficiently wary about what you define as 'static'," he added.
Simply placing a cache in front of a website can take it from secure to vulnerable, Kettle warned.
"Web cache poisoning is far from a theoretical vulnerability, and bloated applications and towering server stacks are conspiring to take it to the masses," Kettle concluded. "Web cache poisoning has long been an elusive vulnerability, a 'theoretical' threat used mostly to scare developers into obediently patching issues that nobody could actually exploit." ®
Updated to add
A spokesperson for the Drupal Security Team has been in touch to say:
James Kettle reported this vulnerability to the Drupal Security Team. We found issues in some Symfony and Zend framework code that Drupal has as a dependency. Symfony and Zend project members worked with us to coordinate a release for those issues which we then packaged and released at https://www.drupal.org/SA-CORE-2018-005.
1Unkeyed inputs refer to parts of a request that a cache ignores, such as the type of browser a user is using, for example. An open source Burp Suite extension called Param Miner automates the process of identifying unkeyed inputs.
2Firefox maintained a list of "recipes" as part of its SHIELD system for silently installing extensions for marketing and research purposes. Mr Robot was among the products promoted using the approach, which triggered something of a backlash.