Skip to content

Commit 61aefc8

Browse files
committed
fix(header): disallow Trailer which were denied by RFC 7230
RFC 7230 section 4.1.2 disallows various headers to be set as trailers. The original list has been extended to include these. This prevents check-time / use-time desynchronization attacks.
1 parent 46aa67e commit 61aefc8

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

httoop/header/messaging.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,21 @@ class Trailer(_HopByHopElement, HeaderElement):
426426

427427
is_response_header = True
428428
is_request_header = True
429-
forbidden_headers = ('Transfer-Encoding', 'Content-Length', 'Trailer')
429+
forbidden_headers = (
430+
# framing
431+
'Transfer-Encoding', 'Content-Length',
432+
# routing
433+
'Host',
434+
# request modifiers (controls, conditionals)
435+
'Expect', 'Max-Forwards',
436+
'If-Match', 'If-None-Match', 'If-Modified-Since', 'If-Unmodified-Since', 'If-Range',
437+
# authentication and state management
438+
'Authorization', 'Proxy-Authorization', 'Cookie', 'Set-Cookie',
439+
# response control data
440+
'Age', 'Cache-Control', 'Expires', 'Date', 'Location', 'Retry-After', 'Vary', 'Warning',
441+
# payload processing
442+
'Content-Encoding', 'Content-Type', 'Content-Range', 'Trailer',
443+
) # fmt: off
430444

431445
def sanitize(self) -> None:
432446
if self.value.title() in self.forbidden_headers:

httoop/parser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from httoop.exceptions import Invalid, InvalidBody, InvalidBodySize, InvalidHeader, InvalidHeaderSize, InvalidLine, InvalidURI
99
from httoop.header import Headers
10+
from httoop.header.messaging import Trailer
1011
from httoop.messages import Message
1112
from httoop.status import BAD_REQUEST, NOT_IMPLEMENTED, PAYLOAD_TOO_LARGE, REQUEST_HEADER_FIELDS_TOO_LARGE
1213
from httoop.util import _, integer
@@ -306,6 +307,11 @@ def parse_trailers(self) -> bool:
306307
exc = InvalidHeader(_('Invalid trailers: %r'), str(exc))
307308
raise BAD_REQUEST(str(exc))
308309

310+
for forbidden in Trailer.forbidden_headers:
311+
if forbidden in self.trailers:
312+
exc = InvalidHeader(_('A Trailer header MUST NOT contain %r field.'), forbidden)
313+
raise BAD_REQUEST(str(exc))
314+
309315
self.merge_trailer_into_header()
310316
return False
311317

0 commit comments

Comments
 (0)