In June 2024, the security world quietly noted the release of CVE-2024-5642, an unusual but important bug in CPython affecting versions 3.9 and earlier. This post aims to break down exactly what went wrong, how the exploit works, why it happened, and what you can do to stay safe.
What is CVE-2024-5642?
This vulnerability is rooted in the way CPython (the standard Python interpreter) handles the configuration of supported NPN protocols via the ssl.SSLContext.set_npn_protocols() method. Specifically, it does not stop you from setting an empty list ([]) when defining what Next Protocol Negotiation (NPN) protocols your application supports.
But here's the tricky part: the underlying OpenSSL API expects at least one protocol in the list—or else bad memory access can happen.
Why Is This a Big Deal?
An empty protocol list is not a legal value for OpenSSL. If you (or a library you use) configures an SSL context with an empty NPN list, OpenSSL may try to read from a buffer that shouldn’t exist. This results in a buffer over-read, which is the core of CVE-2024-5642.
Crash your Python application (DoS attacks)
- Read information from parts of memory that should be inaccessible (if they can trigger the over-read in a specific way)
NPN (Next Protocol Negotiation) is becoming obsolete—ALPN is used almost everywhere today.
- It’s rare and illogical in typical code to specifically set an empty NPN protocol list. Normally, you’d set at least one protocol (for example, "http/1.1").
Let's take a quick look at the problematic Python code
import ssl
ctx = ssl.create_default_context()
ctx.set_npn_protocols([]) # THIS is the problem!
This line passes an empty list to the OpenSSL function inside CPython, which leads to the buffer over-read.
Internally, the problematic code looked like
// Pseudo C code for CPython's handling
int set_npn_protocols(PyObject *self, PyObject *protocols) {
// ...convert Python list to C buffer...
// If protocols is an empty list, buffer length is zero
SSL_CTX_set_next_protos_advertised_cb(ctx, buffer, );
// Underlying C code doesn't expect a zero-length buffer here!
}
OpenSSL, in turn, expects at least one protocol string in the list and doesn't handle zero as a valid length.
How Would Someone Exploit This?
Let's be clear: a successful exploit *requires code that calls* set_npn_protocols([]), either in your own app or a third-party library.
Possible attack scenarios
1. Denial of Service (DoS): Malicious input (or accidental misconfiguration) calls set_npn_protocols([]), causing your app to crash.
2. Memory Disclosure: If the buffer over-read goes far enough, sensitive memory could be leaked, but this is much less likely.
Note: The bug only triggers if you actually call set_npn_protocols with an empty list. If you never use NPN or always provide at least one protocol, you're not affected.
Related Vulnerabilities: OpenSSL CVE-2024-5535
This bug closely interacts with CVE-2024-5535 in OpenSSL, which describes the underlying buffer over-read when given a zero-length NPN protocol buffer.
Any application running CPython 3.9 or older (including most Python 2.x and 3.6–3.9 installs).
- Applications (or libraries) that *actively configure* NPN protocol lists and (critically) pass an empty list.
Here's how you should use set_npn_protocols
import ssl
ctx = ssl.create_default_context()
ctx.set_npn_protocols(['http/1.1', 'spdy/2']) # Good: at least one protocol
Here's how you must NOT use it
import ssl
ctx = ssl.create_default_context()
ctx.set_npn_protocols([]) # Vulnerable: triggers CVE-2024-5642
For Users and Developers
- Upgrade to Python 3.10+ if possible: These versions fix the bug and do not permit an empty list for NPN protocols.
- Review your code and dependencies: Search for all uses of set_npn_protocols and ensure no empty lists are being passed.
- Disable NPN unless required: NPN is replaced by ALPN and is rarely needed. Many modern environments are safe by default.
If you must support CPython <=3.9, add a sanity check
def safe_set_npn_protocols(ctx, protos):
if not protos:
raise ValueError("Protocol list cannot be empty!")
ctx.set_npn_protocols(protos)
More Info and References
- CVE-2024-5642 MITRE page
- Python CVE-2024-5642 Bug Tracker *(Example, replace with real link if available)*
- OpenSSL CVE-2024-5535 Advisory
- Python's ssl module docs
Check your code and third-party libraries.
While this isn’t a high-severity bug for most users, it’s a great reminder to never pass empty protocol lists to SSL-related APIs, and to keep your Python runtime updated.
Timeline
Published on: 06/27/2024 21:15:16 UTC
Last modified on: 11/06/2024 21:35:08 UTC