GeezerVison is showing github.com — SSL releated deprecation for 3.6 · Issue #72209 · python/cpython
SSL releated deprecation for 3.6 #72209Description
| BPO |
28022 |
| Nosy |
@ncoghlan, @orsenthil, @vstinner, @giampaolo, @tiran, @kousu, @alex, @vadmium, @serhiy-storchaka, @dstufft, @Lukasa |
| Files |
ssl_deprecations.patch |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = 'https://github.com/tiran'
closed_at = <Date 2021-04-17.10:48:13.818>
created_at = <Date 2016-09-08.15:19:02.658>
labels = ['type-security', 'expert-SSL', 'library', '3.10', 'docs']
title = 'SSL releated deprecation for 3.6'
updated_at = <Date 2021-08-08.19:17:15.658>
user = 'https://github.com/tiran'
bugs.python.org fields:
activity = <Date 2021-08-08.19:17:15.658>
actor = 'christian.heimes'
assignee = 'christian.heimes'
closed = True
closed_date = <Date 2021-04-17.10:48:13.818>
closer = 'christian.heimes'
components = ['Documentation', 'Library (Lib)', 'SSL']
creation = <Date 2016-09-08.15:19:02.658>
creator = 'christian.heimes'
dependencies = []
files = ['44492']
hgrepos = []
issue_num = 28022
keywords = ['patch']
message_count = 30.0
messages = ['275043', '275056', '275109', '275127', '275129', '275134', '275144', '275230', '275243', '275291', '275300', '275306', '275308', '275603', '275699', '275700', '275726', '275727', '275728', '275730', '275737', '275739', '275767', '275816', '275817', '275843', '275853', '304733', '399231', '399235']
nosy_count = 13.0
nosy_names = ['ncoghlan', 'janssen', 'orsenthil', 'vstinner', 'giampaolo.rodola', 'christian.heimes', 'kousu', 'alex', 'python-dev', 'martin.panter', 'serhiy.storchaka', 'dstufft', 'Lukasa']
pr_nums = []
priority = 'high'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'security'
url = 'https://bugs.python.org/issue28022'
versions = ['Python 3.10']
Activitytiran commented on Sep 8, 2016 I like to deprecate some SSL related parts of Python:
- ssl.wrap_socket() is a horrible abomination. People should use SSLContext.wrap_socket() instead
- all certfile/cert_file, keyfile/key_file and check_hostname arguments. Use context / ssl_context instead.
- make ftplib, imaplib, nntplib, pop3lib, smtplib etc. validate certs by default.
Lukasa commented on Sep 8, 2016 10/10, yes. I will happily provide code review for this. vstinner commented on Sep 8, 2016 tiran commented on Sep 8, 2016 Another deprecation: I like to deprecate all arguments from SSLSocket.__init__() and require users to go through SSLContext.wrap_socket(). It's going to make the implementation much simpler. The argument list is just crazy:
class SSLSocket(socket):
def __init__(self, sock=None, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_TLS, ca_certs=None,
do_handshake_on_connect=True,
family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None,
suppress_ragged_eofs=True, npn_protocols=None, ciphers=None,
server_hostname=None,
_context=None):vstinner commented on Sep 8, 2016 I like the idea of using SSLContext as the obvious and only choice to
"configure" SSL. tiran commented on Sep 8, 2016 memo to me: check if SSLContext.wrap_socket() can deal with a fileno as sock argument. tiran commented on Sep 8, 2016 vadmium commented on Sep 9, 2016 urllib.request.urlopen() should be affected too right? orsenthil commented on Sep 9, 2016 Yes, urllib.request.urlopen needs an update too. It takes those certfile and keyfile and usage of those could be deprecated in favor of context. tiran commented on Sep 9, 2016 I have deprecated cafile, capath and cadefault for urlopen(). The function didn't pop up on my radar because I was looking for certfile and cert_file, not cafile. I also added deprecations to the documentation of SSLSocket.read and write. tiran commented on Sep 11, 2016 The performance benefit is not worth the risk. For 10 httplib requests to pypi.python.org, a shared SSLContext is about 5% faster than a new context for each request. Session resumption improves the simple test case by another 20%. ncoghlan commented on Sep 11, 2016 Leaving the option of context caching entirely to the caller would definitely make things simpler - my main interest is just in avoiding a hard compatibility break for folks that aren't doing anything particularly wrong, by which I mean specifically cases where a wrap_socket() implementation like this one would continue to work for them:
def wrap_socket(sock, *args, *kwds):
return ssl.get_default_context().wrap_socket(sock, *args, **kwds)vadmium commented on Sep 11, 2016 New test failure when using -Werror:
======================================================================
ERROR: test_local_bad_hostname (test.test_httplib.HTTPSTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/media/disk/home/proj/python/cpython/Lib/test/test_httplib.py", line 1646, in test_local_bad_hostname
check_hostname=True)
File "/media/disk/home/proj/python/cpython/Lib/http/client.py", line 1373, in __init__
DeprecationWarning, 2)
DeprecationWarning: key_file, cert_file and check_hostname are deprecated, use a custom context instead.python-dev commented on Sep 11, 2016 tiran commented on Sep 11, 2016 Thanks for the report. "./python -Werror -m test -uall test_httplib" is now passing for me. serhiy-storchaka commented on Sep 11, 2016 test_imaplib is failed too.
======================================================================
ERROR: test_logincapa_with_client_certfile (test.test_imaplib.RemoteIMAP_SSLTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/serhiy/py/cpython-debug/Lib/test/test_imaplib.py", line 641, in test_logincapa_with_client_certfile
_server = self.imap_class(self.host, self.port, certfile=CERTFILE)
File "/home/serhiy/py/cpython-debug/Lib/imaplib.py", line 1273, in __init__
"custom ssl_context instead", DeprecationWarning, 2)
DeprecationWarning: keyfile and certfile are deprecated, use acustom ssl_context instead
python-dev commented on Sep 11, 2016 serhiy-storchaka commented on Oct 22, 2017 Shouldn't this issue be closed?
Since SSL context arguments are not supported in 2.7, the deprecated arguments can't be removed until EOL of 2.7. kousu commented on Aug 8, 2021 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":
|
ssl_context = ssl._create_stdlib_context(certfile=certfile, |
which is actually "ssl._create_unverified_context":
|
_create_stdlib_context = _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:
|
context.check_hostname = check_hostname |
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 :) tiran commented on Aug 8, 2021 The part with "make ftplib, imaplib, nntplib, pop3lib, smtplib etc. validate certs by default" was not implemented. These modules still default to unverified connections.
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|