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.

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 <>
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":

which is actually "ssl._create_unverified_context":

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:

To demonstrate, check out this tester script:

$ cat 
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= USERNAME=test1 PASSWORD=test1test1 python3 
('OK', [b'Logged in'])

I don't have a cert for (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 
import os, ssl, imaplib

ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)

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

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 :)
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: <>
2021-08-08 18:58:29kousulinkissue28022 messages
2021-08-08 18:58:28kousucreate