Squid is able to process Edge Side Includes (ESI) pages when it acts as a reverse proxy. By default, this processing is enabled by default, and can be ‘triggered’ by any page whose response can be manipulated to return a single response header, and content.
ESI is an xml-based markup language which, in layman terms, can be used to cache _specific parts_ of a single web page, thus allowing for the caching of static content on an otherwise dynamically created page.
ESIs are able to make use of certain HTTP headers, such as through boolean operators, checking of certain attributes, and Cookie parsing.
However, Squid’s ESI handling incorrectly assumes that headers will always be less than 65535-bytes long, and uses the String
-type to parse them in some places. This means that, for example, if request_header_max_size
is set to greater than 65535-bytes, Squid will assert when parsing these headers in ESI’s handling, because the String
-type has a hard-coded maximum of 65535-bytes.
There are multiple places this is an issue in Squid’s ESI handling. Notably:
String S (state.header().getList (Http::HdrType::ACCEPT_LANGUAGE));
String strVary (rep->header.getList (Http::HdrType::VARY));
This means that a rogue client can send an extremely long Vary
or Accept-Language
header to Squid when it is in reverse-proxy mode, and if it is using ESIs (or can be tricked into thinking it is using ESIs), it will crash with an assertion.