| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 228a60c commit 4d1cf9f
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -936,14 +936,29 @@ def set_debuglevel(self, level): | |||
| 936 | 936 | self.debuglevel = level | |
| 937 | 937 | ||
| 938 | 938 | def _tunnel(self): | |
| 939 | + if _contains_disallowed_url_pchar_re.search(self._tunnel_host): | ||
| 940 | + raise ValueError('Tunnel host can\'t contain control characters %r' | ||
| 941 | + % (self._tunnel_host,)) | ||
| 939 | 942 | connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host, | |
| 940 | 943 | self._tunnel_port) | |
| 941 | 944 | connect_bytes = connect_str.encode("ascii") | |
| 942 | 945 | self.send(connect_bytes) | |
| 943 | 946 | for header, value in self._tunnel_headers.items(): | |
| 944 | - header_str = "%s: %s\r\n" % (header, value) | ||
| 945 | - header_bytes = header_str.encode("latin-1") | ||
| 946 | - self.send(header_bytes) | ||
| 947 | + if hasattr(header, 'encode'): | ||
| 948 | + header = header.encode('ascii') | ||
| 949 | + | ||
| 950 | + if not _is_legal_header_name(header): | ||
| 951 | + raise ValueError('Invalid header name %r' % (header,)) | ||
| 952 | + | ||
| 953 | + if hasattr(value, 'encode'): | ||
| 954 | + value = value.encode('latin-1') | ||
| 955 | + elif isinstance(value, int): | ||
| 956 | + value = str(value).encode('ascii') | ||
| 957 | + | ||
| 958 | + if _is_illegal_header_value(value): | ||
| 959 | + raise ValueError('Invalid header value %r' % (value,)) | ||
| 960 | + | ||
| 961 | + self.send(header + b': ' + value + b'\r\n') | ||
| 947 | 962 | self.send(b'\r\n') | |
| 948 | 963 | ||
| 949 | 964 | response = self.response_class(self.sock, method=self._method) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -344,6 +344,51 @@ def test_invalid_headers(self): | |||
| 344 | 344 | with self.assertRaisesRegex(ValueError, 'Invalid header'): | |
| 345 | 345 | conn.putheader(name, value) | |
| 346 | 346 | ||
| 347 | + def test_invalid_tunnel_headers(self): | ||
| 348 | + cases = ( | ||
| 349 | + ('Invalid\r\nName', 'ValidValue'), | ||
| 350 | + ('Invalid\rName', 'ValidValue'), | ||
| 351 | + ('Invalid\nName', 'ValidValue'), | ||
| 352 | + ('\r\nInvalidName', 'ValidValue'), | ||
| 353 | + ('\rInvalidName', 'ValidValue'), | ||
| 354 | + ('\nInvalidName', 'ValidValue'), | ||
| 355 | + (' InvalidName', 'ValidValue'), | ||
| 356 | + ('\tInvalidName', 'ValidValue'), | ||
| 357 | + ('Invalid:Name', 'ValidValue'), | ||
| 358 | + (':InvalidName', 'ValidValue'), | ||
| 359 | + ('ValidName', 'Invalid\r\nValue'), | ||
| 360 | + ('ValidName', 'Invalid\rValue'), | ||
| 361 | + ('ValidName', 'Invalid\nValue'), | ||
| 362 | + ('ValidName', 'InvalidValue\r\n'), | ||
| 363 | + ('ValidName', 'InvalidValue\r'), | ||
| 364 | + ('ValidName', 'InvalidValue\n'), | ||
| 365 | + ) | ||
| 366 | + for name, value in cases: | ||
| 367 | + with self.subTest((name, value)): | ||
| 368 | + conn = client.HTTPConnection('example.com') | ||
| 369 | + conn.set_tunnel('tunnel', headers={ | ||
| 370 | + name: value | ||
| 371 | + }) | ||
| 372 | + conn.sock = FakeSocket('') | ||
| 373 | + with self.assertRaisesRegex(ValueError, 'Invalid header'): | ||
| 374 | + conn._tunnel() # Called in .connect() | ||
| 375 | + | ||
| 376 | + def test_invalid_tunnel_host(self): | ||
| 377 | + cases = ( | ||
| 378 | + 'invalid\r.host', | ||
| 379 | + '\ninvalid.host', | ||
| 380 | + 'invalid.host\r\n', | ||
| 381 | + 'invalid.host\x00', | ||
| 382 | + 'invalid host', | ||
| 383 | + ) | ||
| 384 | + for tunnel_host in cases: | ||
| 385 | + with self.subTest(tunnel_host): | ||
| 386 | + conn = client.HTTPConnection('example.com') | ||
| 387 | + conn.set_tunnel(tunnel_host) | ||
| 388 | + conn.sock = FakeSocket('') | ||
| 389 | + with self.assertRaisesRegex(ValueError, 'Tunnel host can\'t contain control characters'): | ||
| 390 | + conn._tunnel() # Called in .connect() | ||
| 391 | + | ||
| 347 | 392 | def test_headers_debuglevel(self): | |
| 348 | 393 | body = ( | |
| 349 | 394 | b'HTTP/1.1 200 OK\r\n' | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Reject CR/LF characters in tunnel request headers for the | ||
| 2 | + HTTPConnection.set_tunnel() method. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments