What Edge Side Includes Are and Why They Are Still Deployed
Edge Side Includes are HTML-like tags processed by a CDN or proxy and replaced with live content before the response reaches the browser. A site uses <esi:include> to embed a shopping cart into an otherwise static e-commerce page, or <esi:vars> to inject a geo-region value into JavaScript — dynamic fragments inside cached responses. The standard dates to 2001 and is implemented in Akamai and Apache Traffic Server as an opt-in feature. Akamai is not at fault for sites that enable it.
“you have ESI which breaks everything” — Robert Vulpe
That opt-in is still active on production targets. Sites keep it for legacy reasons, and because it predates modern security thinking, its attack surface has gone largely unexamined.
Vuln 1 — ESI Injection Overrides Content-Type to Enable XSS on a JSON Endpoint
A collaborator messaged Vulpe on Twitter with a JSON endpoint that reflected ESI tags. The content-type was application/json, which kills XSS — browsers won’t execute scripts in a JSON response. The fix was esi:addheader, which fires at the outermost CDN layer and overwrites every header set below it. That turned the content-type to text/html. The target blocked script and iframe in the input, so Vulpe applied four layers of URL-encoding to slip the tags through. The final payload — addheader + 4x URL-encode + XSS (08:45) exfiltrated the session cookie and proved full account takeover.
“you have ESI which breaks everything” — Robert Vulpe
Vuln 2 — Percent-Encoding the Dot to Defeat Static-File Detection
“if you find something that smells this old it’s going to be so vulnerable” — Robert Vulpe
The second endpoint was a JSON file — normally a static asset Akamai skips ESI processing on, the same way it skips CSS or JS. Vulpe and his collaborator could see their input reflected in the output, but ESI tags weren’t evaluating. Akamai was reading the .json extension and caching the response as-is. The fix was one character: replace the literal dot with %2e. Percent-encoded dot bypasses static-extension check (12:01). Akamai no longer recognized the extension, stopped treating the file as static, and evaluated the ESI tags.
Browser Quirk That Made the Exploit Work — iframe-Only Percent Preservation
The percent-encoded dot trick only worked if the browser left it alone. Chrome normalizes %2e to a literal dot in the address bar, killing the bypass. Firefox and Safari preserve it, but only inside an iframe. Vulpe’s collaborator spent a month on this before finding that narrow delivery path. iframe delivery on Firefox and Safari (14:23) shows the XSS firing through an iframe hosted on a same-scope subdomain, which also cleared the SameSite cookie restriction. Firefox has since relaxed its normalization behavior — the encoded dot now survives even in the address bar — but at the time, the iframe was the only path to account takeover.
Bonuses — Direct Cookie Exfiltration and Automation at Scale
XSS is optional. ESI’s esi:vars reflects $HTTP_COOKIE directly into the response body, so an attacker can exfiltrate a session cookie to a server they control without writing a single script tag. Vulpe noted this during triage — the XSS path gets more money from bug bounty programs, but the cookie path is cleaner.
The 15 targets across this program did not come from manual hunting. Over 18 months, Vulpe and his collaborator ran Automation pipeline — gau + katana + dedup + brute-force params (18:49): gau pulled web-archive URLs, katana crawled live links, a deduplication tool trimmed the list, and parameter brute-forcing did the rest. Most of the 15 findings were basic. The two presented earlier were the exceptions.
Q&A
Are these ESI vulnerabilities the same on all CDNs, including Cloudflare which supports ESI? Vulpe had no direct knowledge of Cloudflare’s behavior, but argued the vulnerability sits with the websites that reflect ESI tags rather than with the CDN itself, since ESI is working as intended. ▶ 19:40
How do we secure against this — what steps are needed to audit a codebase? The affected program removed legacy endpoints, HTML-encoded angle brackets in JSON output, and blocked any ESI keywords at the WAF — Vulpe’s preferred fix was to remove ESI support entirely. ▶ 21:08
Where exactly is the problem — the CDN or the website — and which one should fix it? Responsibility falls on the websites: ESI is an opt-in, Akamai labels it unmaintained legacy, and any site that enables it and reflects user input into ESI tags owns the risk. ▶ 22:37
Notable Quotes
if you find something that smells this old it’s going to be so vulnerable Robert Vulpe · ▶ 10:03
you have ESI which breaks everything Robert Vulpe · ▶ 6:42
you risk it if you use it Robert Vulpe · ▶ 24:03
Key Takeaways
- Treat any reflected ESI tag as a critical injection primitive — cookie theft and XSS require no separate vulnerability.
- Encode the file-extension dot to defeat CDN static-file detection and force ESI evaluation on JSON endpoints.
- Automate ESI surface discovery with gau and katana across all program scope before targeting individual endpoints.
About the Speaker
Robert Vulpe
Hi, my name is Robert. I’m based in Romania. I’ve been part of the lovely bug bounty community for about 5 years. Before taking this road, I’ve been a software engineer for a long time. I’m playing CTFs from time to time with my amigos. I’m also helping out with training young students in cybersecurity, and preparing them for the European Cyber Security Challenge. I love deeply technical bugs, those unseen or “impossible” to exploit. I like to nerd out about cryptography and algorithms.