File tree 2 files changed +33
-0
lines changed
2 files changed +33
-0
lines changed Original file line number Diff line number Diff line change @@ -206,6 +206,9 @@ def validate_headers(headers, hdr_validation_flags):
206
206
# For example, we avoid tuple unpacking in loops because it represents a
207
207
# fixed cost that we don't want to spend, instead indexing into the header
208
208
# tuples.
209
+ headers = _reject_empty_header_names (
210
+ headers , hdr_validation_flags
211
+ )
209
212
headers = _reject_uppercase_header_fields (
210
213
headers , hdr_validation_flags
211
214
)
@@ -229,6 +232,18 @@ def validate_headers(headers, hdr_validation_flags):
229
232
return headers
230
233
231
234
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
+
232
247
def _reject_uppercase_header_fields (headers , hdr_validation_flags ):
233
248
"""
234
249
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,
688
688
with pytest .raises (h2 .exceptions .ProtocolError ):
689
689
list (h2 .utilities .validate_headers (headers , hdr_validation_flags ))
690
690
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
+
691
709
692
710
class TestOversizedHeaders (object ):
693
711
"""
You can’t perform that action at this time.
0 commit comments