From fd67112f40f48a9489f1f3132d8485ac11db9fbf Mon Sep 17 00:00:00 2001 From: "Paul J. Dorn" Date: Thu, 7 Dec 2023 09:31:00 +0100 Subject: [PATCH] Ignore secure_scheme_headers in Trailer section In common configuration unlikely a big security problem in itself you are just fooling the remote about https. However, it is offers an oracle for otherwise invisible proxy request headers, so it might help exploiting other vulnerabilities. --- gunicorn/http/body.py | 2 +- gunicorn/http/message.py | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/gunicorn/http/body.py b/gunicorn/http/body.py index 41fe334b..2ae0eb84 100644 --- a/gunicorn/http/body.py +++ b/gunicorn/http/body.py @@ -51,7 +51,7 @@ class ChunkedReader(object): if done: unreader.unread(buf.getvalue()[2:]) return b"" - self.req.trailers = self.req.parse_headers(buf.getvalue()[:idx]) + self.req.trailers = self.req.parse_headers(buf.getvalue()[:idx], from_trailer=True) unreader.unread(buf.getvalue()[idx + 4:]) def parse_chunked(self, unreader): diff --git a/gunicorn/http/message.py b/gunicorn/http/message.py index 75b36e33..67fffd9e 100644 --- a/gunicorn/http/message.py +++ b/gunicorn/http/message.py @@ -66,7 +66,7 @@ class Message(object): def parse(self, unreader): raise NotImplementedError() - def parse_headers(self, data): + def parse_headers(self, data, from_trailer=False): cfg = self.cfg headers = [] @@ -76,9 +76,13 @@ class Message(object): # handle scheme headers scheme_header = False secure_scheme_headers = {} - if ('*' in cfg.forwarded_allow_ips or - not isinstance(self.peer_addr, tuple) - or self.peer_addr[0] in cfg.forwarded_allow_ips): + if from_trailer: + # nonsense. either a request is https from the beginning + # .. or we are just behind a proxy who does not remove conflicting trailers + pass + elif ('*' in cfg.forwarded_allow_ips or + not isinstance(self.peer_addr, tuple) + or self.peer_addr[0] in cfg.forwarded_allow_ips): secure_scheme_headers = cfg.secure_scheme_headers # Parse headers into key/value pairs paying attention @@ -294,7 +298,7 @@ class Request(Message): self.unreader.unread(data[2:]) return b"" - self.headers = self.parse_headers(data[:idx]) + self.headers = self.parse_headers(data[:idx], from_trailer=False) ret = data[idx + 4:] buf = None