Full Report
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 , 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 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 um6kekdi&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.
Analysis Summary
# Vulnerability: Multi-Vector Edge Side Include (ESI) Injection
## CVE Details
- **CVE ID**: Not explicitly assigned (Product-specific implementation flaws).
- **CVSS Score**: Estimated 8.8 - 9.6 (High/Critical) depending on implementation.
- **CWE**: CWE-74 (Improper Neutralization of Special Elements in Output used by a Downstream Component - 'Injection'), CWE-91 (XML Injection).
## Affected Systems
- **Products**: Caching servers and load balancers using ESI (e.g., Akamai, Varnish, Squid, NodeJS ESI).
- **Versions**: Various (Dependent on the specific vendor's implementation of the ESI specification).
- **Configurations**: Systems that reflect user input into a page that is subsequently processed by an ESI-capable caching engine or reverse proxy.
## Vulnerability Description
Edge Side Include (ESI) is an XML-based markup language used to fetch dynamic content for cached static pages. The vulnerability occurs when an application reflects unvalidated user input into a portion of a page processed by the ESI engine. An attacker can inject ESI tags to trick the server into performing unauthorized actions, such as Server-Side Request Forgery (SSRF), exfiltrating HTTPOnly cookies, or modifying HTTP headers.
In this specific case, the **Akamai WAF** failed to block ESI tags when disguised with XML comments (e.g., `<ESI:include<!--comment--> ...>`), and the ESI engine processed the payload after the WAF passed it.
## Exploitation
- **Status**: Exploited in a private bug bounty program; Proof of Concept (PoC) available in literature.
- **Complexity**: Medium (Requires bypassing WAF rules and understanding specific ESI implementation functions).
- **Attack Vector**: Network (Remote).
## Impact
- **Confidentiality**: **High**. Attackers can exfiltrate `HTTPOnly` session cookies using ESI variables like `$(HTTP_COOKIE)` and SSRF functions.
- **Integrity**: **High**. Attackers can manipulate application logic and headers (e.g., using `add_header` to change `Content-Type` for XSS).
- **Availability**: **Medium**. Potential for 500 errors and service disruption through malformed tags.
## Remediation
### Patches
- There is no single "patch" for ESI injection as it is a design-level flaw in how user input is handled. Vendors like **Akamai** and **Varnish** provide configuration guides to sanitize inputs.
### Workarounds
- **WAF Signature Updates**: Implement strict regex to detect ESI tags including variations with XML comments (e.g., `<!--ESI-->`).
- **Input Validation**: Sanitize or encode all user-supplied data to prevent the reflection of `<` and `>` characters on pages processed by ESI.
- **Disable Unused ESI Functions**: If the environment allows it, disable high-risk functions like `add_header` or the ability to reference `HTTP_COOKIE`.
## Detection
- **Indicators of Compromise**: Presence of ESI tags (`<esi:include`, `<esi:assign`) in server logs or reflected in responses.
- **Detection Methods**: Use the Burp Suite **Active Scan++** extension to identify if ESI comments are being stripped by the backend. Monitor for unexpected outbound requests from caching servers (SSRF).
## References
- GoSecure: Beyond XSS: Edge Side Include Injection - [https://www.gosecure.net/blog/2018/04/03/beyond-xss-edge-side-include-injection/]
- GoSecure: ESI Injection Part 2 - [https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/]
- Original Article: [https://infosecwriteups.com/exploring-the-world-of-esi-injection-b86234e66f91]