This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ssl.match_hostname() ignores extra string after whitespace in IPv4 address
Type: security Stage: resolved
Components: SSL Versions: Python 3.9, Python 3.8, Python 3.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: alex, christian.heimes, dstufft, janssen, lukasz.langa, miss-islington, ned.deily, rschiron, vstinner
Priority: release blocker Keywords: 3.7regression, patch

Created on 2019-07-01 06:47 by christian.heimes, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 14499 closed christian.heimes, 2019-07-01 06:50
PR 14559 merged miss-islington, 2019-07-02 18:40
PR 14560 merged miss-islington, 2019-07-02 18:40
Messages (12)
msg346964 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2019-07-01 06:47
inet_aton accepts trailing characterrs after a valid IP (
https://bugzilla.redhat.com/show_bug.cgi?id=1347549). This, in combination with its use inside ssl.match_hostname, allows the following code to work when it should fail:

import ssl
cert = {'subjectAltName': (('IP Address', '1.1.1.1'),)}
ssl.match_hostname(cert, '1.1.1.1 ; this should not work but does')


The bug was initially found by Dominik Czarnota and reported by Paul Kehrer.

The issue was introduced in commit aef1283ba428e33397d87cee3c54a5110861552d / bpo-32819. Only 3.7 and newer are affected. It's a potential security bug although low severity. For one Python 3.7 and newer no longer use ssl.match_hostname() to verify hostnames and IP addresses of a certificate. Matching is performed by OpenSSL.
msg346980 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-07-01 08:55
> It's a potential security bug although low severity.

What is the worst that can happen with this issue?

Other the client doesn't validate the cert at all, and so this issue has no impact, or the client validates the cert and trusts the CA, but the host isn't fully validated... Ok, but could someone abuse "1.1.1.1 ; this should not work but does"? Does a web browser accept such hostname? Or can it be used to inject SQL or a shell command for example?
msg347121 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2019-07-02 08:32
Ping. At the moment, this is the only release blocker preventing the release of 3.7.4rc2.
msg347122 - (view) Author: Riccardo Schirone (rschiron) Date: 2019-07-02 08:49
As far as I know you can't request a hostname with spaces in it (which seems to be a precondition to trigger this bug) so I think an attacker cannot even create a malicious CA that would be mistakenly accepted by match_hostname.
msg347123 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2019-07-02 09:14
Riccardo, the issue is about parsing the user supplied hostname/ipaddress, not the IPAddress field of the certificate. X.509 certs store IP addresses as fixed-size binary data, 4 bytes for IPv4 or 16 bytes for IPv6. There can't be any additional payload.

The bug is in the code that parses the user supplied "hostname" parameter to ssl.match_hostname(cert, hostname). The bug allows an attacker to pass an IPv4 address with additional content and ssl.match_hostname() ignores this additional content. This example should fail, but does not fail with an exception:

>>> import ssl
>>> cert = {'subjectAltName': [('IP Address', '127.0.0.1 additional payload')]}
>>> ssl.match_hostname(cert, '127.0.0.1')
msg347151 - (view) Author: Łukasz Langa (lukasz.langa) * (Python committer) Date: 2019-07-02 16:37
FTR 3.8b2 is also waiting for this fix due to the expert's (that's you, Christian!) priority setting.
msg347152 - (view) Author: miss-islington (miss-islington) Date: 2019-07-02 18:39
New changeset 477b1b25768945621d466a8b3f0739297a842439 by Miss Islington (bot) (Christian Heimes) in branch 'master':
bpo-37463: match_hostname requires quad-dotted IPv4 (GH-14499)
https://github.com/python/cpython/commit/477b1b25768945621d466a8b3f0739297a842439
msg347154 - (view) Author: miss-islington (miss-islington) Date: 2019-07-02 21:06
New changeset 3cba3d3c55f230a59174a0dfcafb1d4685269e60 by Miss Islington (bot) in branch '3.8':
bpo-37463: match_hostname requires quad-dotted IPv4 (GH-14499)
https://github.com/python/cpython/commit/3cba3d3c55f230a59174a0dfcafb1d4685269e60
msg347155 - (view) Author: miss-islington (miss-islington) Date: 2019-07-02 21:22
New changeset 024ea2170b7c1652a62cc7458e736c63d4970eb1 by Miss Islington (bot) in branch '3.7':
bpo-37463: match_hostname requires quad-dotted IPv4 (GH-14499)
https://github.com/python/cpython/commit/024ea2170b7c1652a62cc7458e736c63d4970eb1
msg347156 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2019-07-02 21:25
Ned, Łukasz, thanks for your patience.
msg347162 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2019-07-02 22:34
New changeset 070fae6d0ff49e63bfd5f2bdc66f8eb1df3b6557 by Ned Deily (Christian Heimes) in branch '3.7':
bpo-37463: match_hostname requires quad-dotted IPv4 (GH-14499)
https://github.com/python/cpython/commit/070fae6d0ff49e63bfd5f2bdc66f8eb1df3b6557
msg347323 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-07-05 09:49
> inet_aton accepts trailing characterrs after a valid IP (
https://bugzilla.redhat.com/show_bug.cgi?id=1347549).

There is a little bit of confusion between getaddrinfo() and inet_aton() here (https://bugzilla.redhat.com/show_bug.cgi?id=1347549 is about getaddrinfo()). getaddrinfo() has been fixed:
https://sourceware.org/bugzilla/show_bug.cgi?id=20018

But glibc devs don't want to fix inet_aton() to keep the backward compatibility ("for historic reasons"): more info in bpo-37495 "socket.inet_aton parsing issue on some libc versions".

This issue is about ssl.match_hostname() which uses internally socket.inet_aton(). ssl.match_hostname() has been fixed to implement further checks to workaround inet_aton() behavior (ignore extra string after a whitespace).

I also removed inet_aton() from the title of this issue to reduce confusion ;-)
History
Date User Action Args
2022-04-11 14:59:17adminsetgithub: 81644
2019-07-05 09:49:51vstinnersetmessages: + msg347323
2019-07-05 09:37:09christian.heimessettitle: ssl.match_hostname() ignores extra string after a space in IPv4 address -> ssl.match_hostname() ignores extra string after whitespace in IPv4 address
2019-07-05 09:35:33vstinnersettitle: socket.inet_aton IP parsing issue in ssl.match_hostname -> ssl.match_hostname() ignores extra string after a space in IPv4 address
2019-07-02 22:34:03ned.deilysetmessages: + msg347162
2019-07-02 21:25:53christian.heimessetstatus: open -> closed
resolution: fixed
messages: + msg347156

stage: patch review -> resolved
2019-07-02 21:22:56miss-islingtonsetmessages: + msg347155
2019-07-02 21:06:37miss-islingtonsetmessages: + msg347154
2019-07-02 18:40:11miss-islingtonsetpull_requests: + pull_request14377
2019-07-02 18:40:00miss-islingtonsetpull_requests: + pull_request14376
2019-07-02 18:39:55miss-islingtonsetnosy: + miss-islington
messages: + msg347152
2019-07-02 16:37:59lukasz.langasetmessages: + msg347151
2019-07-02 09:14:21christian.heimessetmessages: + msg347123
2019-07-02 08:49:22rschironsetnosy: + rschiron
messages: + msg347122
2019-07-02 08:32:12ned.deilysetmessages: + msg347121
2019-07-01 08:55:28vstinnersetnosy: + vstinner
messages: + msg346980
2019-07-01 06:50:48christian.heimessetkeywords: + patch
stage: needs patch -> patch review
pull_requests: + pull_request14315
2019-07-01 06:47:04christian.heimescreate