Lukas' Notes

security web

Definition

Parser Composition

Parser composition is a class of logic vulnerability in which two layers that interpret the same data disagree about its structure, and the disagreement creates a seam the attacker can exploit at the boundary between them. The bug is not a parser bug in either layer — each layer parses its input correctly by its own rules — but a composition bug: the layers were assumed to agree, and they do not.

HTTP Request Smuggling

Front-end and back-end parse the request body differently

An HTTP message body can be sized either by Content-Length or by the chunked Transfer-Encoding header; the spec forbids both at once, but real front-end/back-end pairs disagree about which wins when both are present.

  • the front-end parses the request using Content-Length, sees one long request it forwards to the back-end;
  • the back-end parses the same bytes using Transfer-Encoding, sees the request end early and the remaining bytes as the first line of a new “smuggled” request;
  • the smuggled request runs as if it came from the front-end’s connection — authenticated, trusted, forwarded to the target the attacker chose (the back-end is reading another request the front-end never saw as separate).

See Hypertext Transfer Protocol for the message structure both layers are parsing.

Web Cache Poisoning

The cache and the origin disagree on the cache key

A caching proxy between client and origin decides what to cache and what to serve from cache using some subset of the request as the cache key; the origin server decides what response to send using some possibly different subset.

  • the attacker sends a request whose interpretation differs between the cache key extractor and the origin: an extra header, an unkeyed parameter, a path normalization the cache collapses but the origin does not;
  • the cache stores the poisoned response, keyed to a request it considers equivalent to ordinary ones from the victim;
  • the victim sends its ordinary request, the cache matches it to the poisoned entry, and the victim receives the attacker’s payload as if it came from the origin.

The cache and origin each behaved correctly by their own rules; the seam between the rules is the vulnerability.

Encoding Differentials

Two layers decode the same bytes differently

  • the validator sees input through one normalization (percent-decoding once, case-folding, stripping a prefix) and judges it inert;
  • the consumer sees the same bytes through another normalization (percent-decoding twice, no case-fold, preserving the prefix) and judges them active code or a different directive.

Bytes the validator classified as inert reach the consumer as a live payload — same bytes, two readings, applied in order. This is SQL injection in URL-encoded form, XSS across a templating boundary, or command injection across a shell boundary in miniature.

Insight

No single parser is at fault

The shared property is that no single layer has a bug. Each layer parses consistently with its own grammar. The vulnerability is the gap between the grammars, and so the structural fix is always to make one layer authoritative — either pin a single parser that both layers use, or canonicalise the data once at the trust boundary and refuse to re-parse downstream. Defense in depth creates more parsers, not fewer; defense at the seam collapses them. See mixing code and data is the root of web injection for the separation-of-code-and-data principle the parser-composition class bends.