Skip to content

Commit 38544cc

Browse files
committed
gh-161104: Check the http.client tunnel host after IDNA encoding
IDNA normalization maps U+00A0 and similar characters to an ASCII space, so check the encoded host that is put into the CONNECT request line.
1 parent 9c0cfb1 commit 38544cc

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

‎Lib/http/client.py‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,11 +1010,15 @@ def _wrap_ipv6(self, ip):
10101010
return ip
10111011

10121012
def _tunnel(self):
1013-
if _contains_disallowed_url_pchar_re.search(self._tunnel_host):
1013+
# Check the host as it is sent: the IDNA codec normalizes the name
1014+
# first (NFKC), which maps some non-ASCII characters to ASCII ones,
1015+
# e.g. U+00A0 (NO-BREAK SPACE) to a space.
1016+
tunnel_host = self._tunnel_host.encode("idna")
1017+
if _contains_disallowed_url_pchar_re.search(tunnel_host.decode("ascii")):
10141018
raise ValueError('Tunnel host can\'t contain control characters %r'
10151019
% (self._tunnel_host,))
10161020
connect = b"CONNECT %s:%d %s\r\n" % (
1017-
self._wrap_ipv6(self._tunnel_host.encode("idna")),
1021+
self._wrap_ipv6(tunnel_host),
10181022
self._tunnel_port,
10191023
self._http_vsn_str.encode("ascii"))
10201024
headers = [connect]

‎Lib/test/test_httplib.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,11 @@ def test_invalid_tunnel_host(self):
405405
'invalid.host\r\n',
406406
'invalid.host\x00',
407407
'invalid host',
408+
# The IDNA codec normalizes these to an ASCII space
409+
'invalid\xa0host',
410+
'invalid\u3000host',
411+
# ... and this one to a space and a combining character
412+
'invalid\xa8host',
408413
)
409414
for tunnel_host in cases:
410415
with self.subTest(tunnel_host):
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix :meth:`http.client.HTTPConnection.set_tunnel` accepting a tunnel host
2+
containing a non-ASCII character that IDNA encoding maps to a space, such as
3+
U+00A0 NO-BREAK SPACE. Connecting now raises :exc:`ValueError`, as it already
4+
does for an ASCII space.

0 commit comments

Comments
 (0)