Edge Side Include (
ESI)is a small set of XML tags in HTTP solutions, like caching or a reverse proxy, to fetch more information about a page for which a template is cached. For instance, a caching server has a page that is mostly static but with a single piece of dynamic content. ESI would allow the developers to replace the dynamic portion of a page when it is processed.
If an attacker can reflect ESI tags in the response or part of the static page, then ESI injection occurs. This can lead to SSRF via specifying a request to make for the data, XSS, HTTPOnly cookie bypass and many other bad issues. The article above has a list of software that supports it, including NodeJS ESI, squid3, fasly, Akamai and many others. The specification for ESI is not always fully implemented though.
The author was looking through the page source and noticed an ESI tag (why would this be in the source of JS though?). The WAF in front blocked the attempted ESI include payloads but didn't block <esi:>, which produced 500 errors. Additionally, the Burp Suite scanner found that it was possible since the comments were being removed but everything else was kept.
The author of the post decided to collaborate with a friend on the bug. Their friend found XSS within a half hour of trying. A tweet is mentioned using <!--esi .... --> within a payload to bypass the parsing and still get the ESI parsed. I don't know HOW this get parsed but the comment seems to simply be removed. Now, the WAF doesn't stop it and the payload works.
Some ESI implementations are SUPER powerful. The original payload is um6k<!--esi $(QUERY_STRING{countryCode}) --><!--esx-->ekdi&countryCode="}};prompt.call(null,origin);//US. The idea is to use the comment to make the WAF not block it then reference the countryCode parameter in the URL with the QUERY_STRING code to get XSS. Since ESI is so powerful, we can concatenate strings and do lots of things.
To make matters worse, this implementation supported the usage of cookies in the check. So, the ESI injection could be used to reference an HTTPOnly protected cookie! If a user clicked on a malicious link, this would lead to complete compromise. To exfiltrate the data, they used XSS and the concatenated session cookie to get the data.
While browsing another subdomain of the company, they found another ESI injection bug. They noticed that the HTTP_COOKIE could not be referenced because of weird transformations. So, they used the function url_decode within ESI. Akamai doesn't see this as an issue and does no transformations on it. They used the SSRF to their own site with the cookie to exfiltrate it.
They found ANOTHER endpoint that was vulnerable as well but with different blocking rules. The ESI injection was in a application/json endpoint, meaning the XSS approach wouldn't work. So, they simply changed the content type using ESI (lolz) using the add_header function. They even found a few of these until the company told them to stop looking for ESI injection bugs!
Overall, an interesting masterclass on ESI injection bugs! In the future, I'm curious to see how popular ESI really is.