Author kousu
Recipients Lukasa, alex, christian.heimes, dstufft, giampaolo.rodola, janssen, kousu, martin.panter, ncoghlan, orsenthil, python-dev, serhiy.storchaka, vstinner
Date 2021-08-08.18:58:28
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1628449109.02.0.753390831824.issue28022@roundup.psfhosted.org>
In-reply-to
Content
Hello everyone, and thank you as usual for all your hard work keeping the python ecosystem going.

I saw that the start of this thread said it was going to

> - make ftplib, imaplib, nntplib, pop3lib, smtplib etc. validate certs by default.

but this hasn't been done, at least not for imaplib. imaplib is still calling the undocumented "ssl._create_stdlib_context":

https://github.com/python/cpython/blob/2b496e79293a8b80e8ba0e514e186b3b1467b64b/Lib/imaplib.py#L1320

which is actually "ssl._create_unverified_context":

https://github.com/python/cpython/blob/2b496e79293a8b80e8ba0e514e186b3b1467b64b/Lib/ssl.py#L842

which is indeed unverified: despite defaulting to PROTOCOL_TLS_CLIENT, which "enables CERT_REQUIRED and check_hostname by default.", it overrides that by setting check_hostname=False:

https://github.com/python/cpython/blob/2b496e79293a8b80e8ba0e514e186b3b1467b64b/Lib/ssl.py#L811



To demonstrate, check out this tester script:

$ cat a.py 
import os, imaplib

with imaplib.IMAP4_SSL(os.environ.get('HOSTNAME')) as S: 
    print(S.login(os.environ.get('USERNAME'), os.environ.get('PASSWORD')))
$ HOSTNAME=46.23.90.174 USERNAME=test1 PASSWORD=test1test1 python3 a.py 
('OK', [b'Logged in'])

I don't have a cert for 46.23.90.174 (no one will give out certs for IPs!), so this is wrong!

In order to actually enable verification you need to know the incantation. It's not that long but it is subtle and frighteningly easy to get wrong. Here it is:

$ cat a.py 
import os, ssl, imaplib

ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_default_certs()

with imaplib.IMAP4_SSL(os.environ.get('HOSTNAME'), ssl_context=ctx) as S: 
    print(S.login(os.environ.get('USERNAME'), os.environ.get('PASSWORD')))
$ HOSTNAME=46.23.90.174 USERNAME=test1 PASSWORD=test1test1 python3 a.py 
Traceback (most recent call last):
  File "a.py", line 6, in <module>
    with imaplib.IMAP4_SSL(os.environ.get('HOSTNAME'), ssl_context=ctx) as S: 
  File "/usr/lib/python3.6/imaplib.py", line 1288, in __init__
    IMAP4.__init__(self, host, port)
  File "/usr/lib/python3.6/imaplib.py", line 198, in __init__
    self.open(host, port)
  File "/usr/lib/python3.6/imaplib.py", line 1301, in open
    IMAP4.open(self, host, port)
  File "/usr/lib/python3.6/imaplib.py", line 299, in open
    self.sock = self._create_socket()
  File "/usr/lib/python3.6/imaplib.py", line 1293, in _create_socket
    server_hostname=self.host)
  File "/usr/lib/python3.6/ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "/usr/lib/python3.6/ssl.py", line 817, in __init__
    self.do_handshake()
  File "/usr/lib/python3.6/ssl.py", line 1077, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.6/ssl.py", line 694, in do_handshake
    match_hostname(self.getpeercert(), self.server_hostname)
  File "/usr/lib/python3.6/ssl.py", line 327, in match_hostname
    % (hostname, ', '.join(map(repr, dnsnames))))
ssl.CertificateError: hostname '46.23.90.174' doesn't match either of 'comms.kousu.ca', 'comms3.kousu.ca'


I can see from this thread there were some concerns about breaking people's self-signed certs back in 2016. But it's five years later now and letsencrypt is super common now, and most servers and clients are enforcing TLS, especially when credentials are involved.

Could this be revisited?

Thanks for any attention you have gifted to this :)
History
Date User Action Args
2021-08-08 18:58:29koususetrecipients: + kousu, ncoghlan, janssen, orsenthil, vstinner, giampaolo.rodola, christian.heimes, alex, python-dev, martin.panter, serhiy.storchaka, dstufft, Lukasa
2021-08-08 18:58:29koususetmessageid: <1628449109.02.0.753390831824.issue28022@roundup.psfhosted.org>
2021-08-08 18:58:29kousulinkissue28022 messages
2021-08-08 18:58:28kousucreate