Did it ever cross your mind that accessing links such as https://www.paypal.com/myaccount/home/stylesheet.css or https://www.paypal.com/myaccount/settings/notifications/logo.png might expose your sensitive data, and even allow attackers to take control over your account?
Web cache deception is a new web attack vector that puts various technologies and frameworks at risk.
A few words about caching and reactions
- Websites often tend to use web cache functionality (for example over a CDN, a load balancer, or simply a reverse proxy). The purpose is simple: store files that are often retrieved, to reduce latency from the web server.
Let’s see an example of web cache. Website http://www.example.com is configured to go through a reverse proxy. A dynamic page that is stored on the server and returns personal content of users, such as http://www.example.com/home.php, will have to create it dynamically per user, since the data is different for each user. This kind of data, or at least its personalized parts, isn’t cached.
What’s more reasonable and common to cache are static, public files: style sheets (css), scripts (js), text files (txt), images (png, bmp, gif), etc. This makes sense because these files usually don’t contain any sensitive information. In addition, as can be found in various best practices articles about web cache configuration, it’s recommended to cache all static files that are meant to be public, and disregard their HTTP caching headers.
- The web cache deception attack counts on similar browsers’ and web servers’ reactions, in the same way as the RPO attack, explained in http://www.thespanner.co.uk/2014/03/21/rpo/ and http://blog.innerht.ml/rpo-gadgets/:
What happens when accessing a URL like http://www.example.com/home.php/non-existent.css?
A GET request to that URL will be produced by the browser. The interesting thing is the server’s reaction – how does it interpret the request URL? Depending on its technology and configuration (the URL structure might need to be built slightly different for different servers), the server returns the content of http://www.example.com/home.php. And yes, the URL remains http://www.example.com/home.php/non-existent.css. The HTTP headers will be the same as for accessing http://www.example.com/home.php directly: same caching headers and same content type (text/html, in this case).
Done with the introduction
What happens if we access http://www.example.com/home.php/non-existent.css, while web cache for static files is set on the proxy server, disregarding caching headers for this kind of file? Let’s analyze this process:
- Browser requests http://www.example.com/home.php/non-existent.css.
- Server returns the content of http://www.example.com/home.php, most probably with HTTP caching headers that instruct to not cache this page.
- The response goes through the proxy.
- The proxy identifies that the file has a css extension.
- Under the cache directory, the proxy creates a directory named home.php, and caches the imposter “CSS” file (non-existent.css) inside.
Usually websites don’t require authentication to access their public static files. Therefore, the cached files are publicly-accessible – no authentication required.
So basically, two conditions are required for this vulnerability to exist:
- Web cache functionality is set for the web application to cache files by their extensions, disregarding any caching header.
- When accessing a page like http://www.example.com/home.php/non-existent.css, the web server will return the content of “home.php” for that URL.
- Configure the cache mechanism to cache files only if their HTTP caching headers allow. That will solve the root cause of this issue.
- If the cache component provides the option, configure it to cache files by their content type.
- Configure the web server so that for pages such as http://www.example.com/home.php/non-existent.css, the web server doesn’t return the content of “home.php” with this URL. Instead, for example, the server should respond with a 404 or 302 response.