varnishcache/varnish-cache

HTTP/2 field values aren't properly validated

kenballus opened this issue · 2 comments

Expected Behavior

Varnish should respond 400, then close the stream when it receives an HTTP/2 request with a field value that begins or ends with ASCII whitespace, as the standard requires.

Current Behavior

RFC 9113 Section 8.2.1 says this:

A field value MUST NOT start or end with an ASCII whitespace character (ASCII SP or HTAB, 0x20 or 0x09).

Varnish does not enforce this check.

Possible Solution

No response

Steps to Reproduce (for bugs)

  • Configure Varnish with the following config file, where PROXY_BACKEND_PLACEHOLDER is the address of a server you control:
vcl 4.1;

backend default {
    .host = "PROXY_BACKEND_PLACEHOLDER";
    .port = "80";
}
  • Send it the following HTTP/2 request:
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00E\x01\x05\x00\x00\x00\x01\x00\n:authority\tlocalhost\x00\x05:path\x01/\x00\x07:method\x03GET\x00\x07:scheme\x04http\x00\x05test1\x03\ta\t
  • Varnish should forward the following HTTP/1.1 request to your server:
GET / HTTP/1.1\r\nhost: localhost\r\nscheme: http\r\ntest1: \ta\t\r\nX-Forwarded-For: <IP OMITTED>\r\nVia: 1.1 5852af6c7656 (Varnish/trunk)\r\nAccept-Encoding: gzip\r\nX-Varnish: 32769\r\n\r\n
  • Note that this request contains a header value that both begins and ends with \t.

Context

I am a security researcher working on HTTP request smuggling. Primitives like this one, while not exploitable on their own, are potentially useful in request smuggling exploit chains.

Varnish Cache version

varnishd (varnish-trunk revision 8bfc594)

Operating system

Alpine Linux 3.18.0

Source of binary packages used (if any)

No response

dridi commented

Hi, please consider this if you find anything serious in your security research: https://varnish-cache.org/security/