File tree Expand file tree Collapse file tree 2 files changed +34
-0
lines changed Expand file tree Collapse file tree 2 files changed +34
-0
lines changed Original file line number Diff line number Diff line change @@ -206,6 +206,9 @@ def validate_headers(headers, hdr_validation_flags):
206206 # For example, we avoid tuple unpacking in loops because it represents a
207207 # fixed cost that we don't want to spend, instead indexing into the header
208208 # tuples.
209+ headers = _reject_empty_header_names (
210+ headers , hdr_validation_flags
211+ )
209212 headers = _reject_uppercase_header_fields (
210213 headers , hdr_validation_flags
211214 )
@@ -229,6 +232,19 @@ def validate_headers(headers, hdr_validation_flags):
229232 return headers
230233
231234
235+ def _reject_empty_header_names (headers , hdr_validation_flags ):
236+ """
237+ Raises a ProtocolError if any header names are empty (length 0).
238+ While hpack decodes such headers without errors, they are semantically
239+ forbidden in HTTP, see RFC 7230, stating that they must be at least one
240+ character long.
241+ """
242+ for header in headers :
243+ if len (header [0 ]) == 0 :
244+ raise ProtocolError ("Received header name with zero length." )
245+ yield header
246+
247+
232248def _reject_uppercase_header_fields (headers , hdr_validation_flags ):
233249 """
234250 Raises a ProtocolError if any uppercase character is found in a header
Original file line number Diff line number Diff line change @@ -688,6 +688,24 @@ def test_inbound_resp_header_extra_pseudo_headers(self,
688688 with pytest .raises (h2 .exceptions .ProtocolError ):
689689 list (h2 .utilities .validate_headers (headers , hdr_validation_flags ))
690690
691+ @pytest .mark .parametrize ('hdr_validation_flags' , hdr_validation_combos )
692+ def test_inbound_header_name_length (self , hdr_validation_flags ):
693+ with pytest .raises (h2 .exceptions .ProtocolError ):
694+ list (h2 .utilities .validate_headers ([(b'' , b'foobar' )], hdr_validation_flags ))
695+
696+ def test_inbound_header_name_length_full_frame_decode (self , frame_factory ):
697+ f = frame_factory .build_headers_frame ([])
698+ f .data = b"\x00 \x00 \x05 \x00 \x00 \x00 \x00 \x04 "
699+ data = f .serialize ()
700+
701+ c = h2 .connection .H2Connection (config = h2 .config .H2Configuration (client_side = False ))
702+ c .initiate_connection ()
703+ c .receive_data (frame_factory .preamble ())
704+ c .clear_outbound_data_buffer ()
705+
706+ with pytest .raises (h2 .exceptions .ProtocolError , match = "Received header name with zero length." ):
707+ c .receive_data (data )
708+
691709
692710class TestOversizedHeaders (object ):
693711 """
You can’t perform that action at this time.
0 commit comments