Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2023-40217: Bypass TLS handshake on closed sockets #108310

Closed
2 tasks done
ambv opened this issue Aug 22, 2023 · 11 comments
Closed
2 tasks done

CVE-2023-40217: Bypass TLS handshake on closed sockets #108310

ambv opened this issue Aug 22, 2023 · 11 comments
Assignees
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes 3.12 bugs and security fixes 3.13 new features, bugs and security fixes type-bug An unexpected behavior, bug, or error type-security A security issue

Comments

@ambv
Copy link
Contributor

ambv commented Aug 22, 2023

Bug report

Originally reported by @aapooksman via the Python Security Response Team mailing list on 2023-08-08. Thanks for the responsible disclosure!

Checklist

  • I am confident this is a bug in CPython, not a bug in a third-party project
  • I have searched the CPython issue tracker,
    and am confident this bug has not been reported before

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, CPython main branch

Operating systems tested on:

Linux, macOS

A clear and concise description of the bug:

Instances of ssl.SSLSocket are vulnerable to a bypass of the TLS handshake and included protections (like certificate verification) and could lead applications to treat unencrypted data received pre-TLS-handshake that is followed by an immediate connection close as if it were post-handshake TLS encrypted data.

Linked PRs

@ambv ambv added type-bug An unexpected behavior, bug, or error type-security A security issue labels Aug 22, 2023
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit to ambv/cpython that referenced this issue Aug 22, 2023
…ose flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
@ambv ambv changed the title Placeholder issue CVE-2023-40217: Bypass TLS handshake on closed sockets Aug 22, 2023
@ambv ambv added 3.11 only security fixes 3.10 only security fixes 3.9 only security fixes 3.8 only security fixes 3.12 bugs and security fixes 3.13 new features, bugs and security fixes labels Aug 22, 2023
ambv added a commit that referenced this issue Aug 22, 2023
…aw (#108315)

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit that referenced this issue Aug 22, 2023
…lose flaw (#108317)

gh-108310: Fix CVE-2023-40217: Check for & avoid the ssl pre-close flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit that referenced this issue Aug 22, 2023
…lose flaw (#108318)

gh-108310: Fix CVE-2023-40217: Check for & avoid the ssl pre-close flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit that referenced this issue Aug 22, 2023
…ose flaw (#108321)

gh-108310: Fix CVE-2023-40217: Check for & avoid the ssl pre-close flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit that referenced this issue Aug 22, 2023
…ose flaw (#108320)

gh-108310: Fix CVE-2023-40217: Check for & avoid the ssl pre-close flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
ambv added a commit that referenced this issue Aug 22, 2023
…lose flaw (#108316)

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
@ambv
Copy link
Contributor Author

ambv commented Aug 22, 2023

We'll keep this open until the relevant Python releases are made.

ambv pushed a commit to ambv/cpython that referenced this issue Aug 24, 2023
…ythonGH-108370)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue pythongh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv pushed a commit to ambv/cpython that referenced this issue Aug 24, 2023
…ythonGH-108370)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue pythongh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv added a commit that referenced this issue Aug 24, 2023
…8370) (#108404)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue gh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv added a commit that referenced this issue Aug 24, 2023
…8370) (#108405)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue gh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv added a commit that referenced this issue Aug 24, 2023
…8370) (#108406)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue gh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv added a commit that referenced this issue Aug 24, 2023
) (#108407)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue gh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
ambv added a commit that referenced this issue Aug 24, 2023
) (#108408)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue gh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)
@ambv
Copy link
Contributor Author

ambv commented Aug 24, 2023

3.11.5, 3.10.13, 3.9.18, and 3.8.18 are released. Python 3.12 is still in pre-release, RC2 with the fix planned for September 4th. This issue can be closed. Thanks, everyone!

@ambv ambv closed this as completed Aug 24, 2023
@Byefsaneahmet

This comment was marked as abuse.

@Byefsaneahmet

This comment was marked as abuse.

@Byefsaneahmet

This comment was marked as abuse.

@hugovk
Copy link
Member

hugovk commented Sep 8, 2023

I've reported @Byefsaneahmet to GitHub for disruption.

bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this issue Sep 14, 2023
https://build.opensuse.org/request/show/1110909
by user mcepl + anag+factory
Forwarded request #1110536 from dgarcia

- Add CVE-2023-40217-avoid-ssl-pre-close.patch fixing
    gh#python/cpython#108310, backport from upstream patch
    gh#python/cpython#108315
    (bsc#1214692, CVE-2023-40217)
carlosroman pushed a commit to DataDog/cpython that referenced this issue Oct 11, 2023
…pre-close flaw (python#108320)

pythongh-108310: Fix CVE-2023-40217: Check for & avoid the ssl pre-close flaw

Instances of `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.

The vulnerability is caused when a socket is connected, data is sent by the
malicious peer and stored in a buffer, and then the malicious peer closes the
socket within a small timing window before the other peers’ TLS handshake can
begin. After this sequence of events the closed socket will not immediately
attempt a TLS handshake due to not being connected but will also allow the
buffered data to be read as if a successful TLS handshake had occurred.

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
carlosroman pushed a commit to DataDog/cpython that referenced this issue Oct 11, 2023
…thonGH-108344) (python#108351)

Explicitly break a reference cycle when SSLSocket._create() raises an
exception. Clear the variable storing the exception, since the
exception traceback contains the variables and so creates a reference
cycle.

This test leak was introduced by the test added for the fix of pythonGH-108310.
(cherry picked from commit 64f9935)

Co-authored-by: Victor Stinner <vstinner@python.org>
carlosroman pushed a commit to DataDog/cpython that referenced this issue Oct 11, 2023
…ythonGH-108370) (python#108407)

* In preauth tests of test_ssl, explicitly break reference cycles
  invoving SingleConnectionTestServerThread to make sure that the
  thread is deleted. Otherwise, the test marks the environment as
  altered because the threading module sees a "dangling thread"
  (SingleConnectionTestServerThread). This test leak was introduced
  by the test added for the fix of issue pythongh-108310.
* Use support.SHORT_TIMEOUT instead of hardcoded 1.0 or 2.0 seconds
  timeout.
* SingleConnectionTestServerThread.run() catchs TimeoutError
* Fix a race condition (missing synchronization) in
  test_preauth_data_to_tls_client(): the server now waits until the
  client connect() completed in call_after_accept().
* test_https_client_non_tls_response_ignored() calls server.join()
  explicitly.
* Replace "localhost" with server.listener.getsockname()[0].
(cherry picked from commit 592bacb)

Co-authored-by: Victor Stinner <vstinner@python.org>
frenzymadness added a commit to frenzymadness/cpython that referenced this issue Oct 11, 2023
The new class is part of the fix for CVE-2023-40217:
python@b4bcc06
but it's not in the lists of tests so they're not
executed. The new tests also need `SHORT_TIMEOUT`
constant not available in test.support in 3.8.
@bastien-roucaries
Copy link

Hi I have difficulty to port this to python3.5 it fail async io test... Can I get nsome help from upstream ?

@vstinner
Copy link
Member

vstinner commented Nov 1, 2023

@mcepl: Maybe you backported this change to 3.5 for OpenSUSE?

@bastien-roucaries
Copy link

@mcepl
Copy link
Contributor

mcepl commented Nov 1, 2023

@mcepl: Maybe you backported this change to 3.5 for OpenSUSE?

True. I have here
CVE-2023-40217-avoid-ssl-pre-close-Python34.patch and
CVE-2023-40217-avoid-ssl-pre-close-Python36.patch.txt and
CVE-2023-40217-avoid-ssl-pre-close-Python27.patch.txt, just to be complete.

ambv added a commit that referenced this issue Jan 17, 2024
The new class is part of the fix for CVE-2023-40217:
b4bcc06
but it's not in the lists of tests so they're not
executed. The new tests also need `SHORT_TIMEOUT`
constant not available in test.support in 3.8.

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
mcepl pushed a commit to openSUSE-Python/cpython that referenced this issue Apr 4, 2024
Instances of `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.

The vulnerability is caused when a socket is connected, data is
sent by the malicious peer and stored in a buffer, and then the
malicious peer closes the socket within a small timing window
before the other peers’ TLS handshake can begin. After this
sequence of events the closed socket will not immediately attempt
a TLS handshake due to not being connected but will also allow
the buffered data to be read as if a successful TLS handshake had
occurred.

Code is from gh#python/cpython@b4bcc06, it was released
upstream in 3.8.18.

Co-Authored-By: Gregory P. Smith [Google LLC] <greg@krypto.org>
Fixes: bsc#1214692
Fixes: gh#python#108315
Fixes: gh#python#108310
Patch: CVE-2023-40217-avoid-ssl-pre-close.patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.8 only security fixes 3.9 only security fixes 3.10 only security fixes 3.11 only security fixes 3.12 bugs and security fixes 3.13 new features, bugs and security fixes type-bug An unexpected behavior, bug, or error type-security A security issue
Projects
None yet
Development

No branches or pull requests

7 participants