Skip to content

Commit

Permalink
Roll back fix for CVE-2023-40217
Browse files Browse the repository at this point in the history
The community rolled back the original fix because of problems.

This may be fixed in the future with pythongh-102988

Cherry picked b4bcc06 for SSL
  • Loading branch information
rickprice committed Sep 12, 2023
1 parent f2707a6 commit 6030000
Show file tree
Hide file tree
Showing 5 changed files with 430 additions and 1 deletion.
11 changes: 11 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2636,3 +2636,14 @@ characters. Leading WHATWG C0 control and space characters are now stripped
from the URL. This is a mitigation for `CVE-2023-24329
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-24329>`_.

Notable security feature in 3.7.17.2
==================================

Fixed an issue where instances of :class:`ssl.SSLSocket` were vulnerable to
a bypass of the TLS handshake and included protections (like certificate
verification) and treating sent unencrypted data as if it were
post-handshake TLS encrypted data. Security issue reported as
`CVE-2023-40217
<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-40217>`_ by Aapo
Oksman. Patch by Gregory P. Smith.

31 changes: 30 additions & 1 deletion Lib/ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
)
self = cls.__new__(cls, **kwargs)
super(SSLSocket, self).__init__(**kwargs)
self.settimeout(sock.gettimeout())
sock_timeout = sock.gettimeout()
sock.detach()

self._context = context
Expand All @@ -851,9 +851,38 @@ def _create(cls, sock, server_side=False, do_handshake_on_connect=True,
if e.errno != errno.ENOTCONN:
raise
connected = False
blocking = self.getblocking()
self.setblocking(False)
try:
# We are not connected so this is not supposed to block, but
# testing revealed otherwise on macOS and Windows so we do
# the non-blocking dance regardless. Our raise when any data
# is found means consuming the data is harmless.
notconn_pre_handshake_data = self.recv(1)
except OSError as e:
# EINVAL occurs for recv(1) on non-connected on unix sockets.
if e.errno not in (errno.ENOTCONN, errno.EINVAL):
raise
notconn_pre_handshake_data = b''
self.setblocking(blocking)
if notconn_pre_handshake_data:
# This prevents pending data sent to the socket before it was
# closed from escaping to the caller who could otherwise
# presume it came through a successful TLS connection.
reason = "Closed before TLS handshake with data in recv buffer."
notconn_pre_handshake_data_error = SSLError(e.errno, reason)
# Add the SSLError attributes that _ssl.c always adds.
notconn_pre_handshake_data_error.reason = reason
notconn_pre_handshake_data_error.library = None
try:
self.close()
except OSError:
pass
raise notconn_pre_handshake_data_error
else:
connected = True

self.settimeout(sock_timeout) # Must come after setblocking() calls.
self._connected = connected
if connected:
# create the SSL object
Expand Down
Loading

0 comments on commit 6030000

Please sign in to comment.