VYPR
High severityNVD Advisory· Published Mar 17, 2026· Updated Mar 18, 2026

pyOpenSSL DTLS cookie callback buffer overflow

CVE-2026-27459

Description

pyOpenSSL is a Python wrapper around the OpenSSL library. Starting in version 22.0.0 and prior to version 26.0.0, if a user provided callback to set_cookie_generate_callback returned a cookie value greater than 256 bytes, pyOpenSSL would overflow an OpenSSL provided buffer. Starting in version 26.0.0, cookie values that are too long are now rejected.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

pyOpenSSL A buffer overflow vulnerability in pyOpenSSL versions 22.0.0 to 25.3.0 allows a DTLS cookie callback to overflow a fixed-size buffer if it returns a cookie longer than 256 bytes.

Vulnerability

pyOpenSSL, a Python wrapper around the OpenSSL library, contains a buffer overflow vulnerability in its DTLS cookie generation callback. In affected versions (22.0.0 through 25.3.0), if a user-provided callback registered via set_cookie_generate_callback returns a cookie value exceeding 256 bytes, pyOpenSSL would write that oversized cookie into a fixed-size buffer provided by OpenSSL, causing a buffer overflow [1][2][4]. The root cause is the absence of a length check before copying the callback's return value into the output buffer.

Exploitation

To exploit this vulnerability, an attacker must be able to influence the cookie value returned by the callback. This typically requires the attacker to control the server-side application logic that defines the callback, or to trigger a scenario where the callback returns an attacker-controlled value. The vulnerability is triggered during a DTLS handshake when the server generates a cookie and copies it into the OpenSSL-provided buffer. No authentication is required to trigger the overflow if the callback is already set to return a long value.

Impact

A successful buffer overflow can lead to memory corruption, potentially allowing an attacker to crash the application (denial of service) or achieve arbitrary code execution in the context of the process using pyOpenSSL. The severity is high because DTLS is commonly used in real-time communication and IoT applications where memory safety is critical.

Mitigation

The vulnerability is fixed in pyOpenSSL version 26.0.0, released on 2026-03-15 [1][3]. In this version, cookie values longer than DTLS1_COOKIE_LENGTH (255 bytes) are rejected with a ValueError before being written to the buffer [3]. Users are strongly advised to upgrade to version 26.0.0 or later. No workarounds are documented; the only mitigation is to update the library.

AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pyopensslPyPI
>= 22.0.0, < 26.0.026.0.0

Affected products

2

Patches

1
57f09bb4bb05

Fix buffer overflow in DTLS cookie generation callback (#1479)

https://github.com/pyca/pyopensslAlex GaynorFeb 18, 2026via ghsa
3 files changed · +46 0
  • CHANGELOG.rst+1 0 modified
    @@ -19,6 +19,7 @@ Deprecations:
     Changes:
     ^^^^^^^^
     
    +- Properly raise an error if a DTLS cookie callback returned a cookie longer than ``DTLS1_COOKIE_LENGTH`` bytes. Previously this would result in a buffer-overflow.
     - Added ``OpenSSL.SSL.Connection.get_group_name`` to determine which group name was negotiated.
     - ``Context.set_tlsext_servername_callback`` now handles exceptions raised in the callback by calling ``sys.excepthook`` and returning a fatal TLS alert. Previously, exceptions were silently swallowed and the handshake would proceed as if the callback had succeeded.
     
    
  • src/OpenSSL/SSL.py+7 0 modified
    @@ -717,11 +717,18 @@ class _CookieGenerateCallbackHelper(_CallbackExceptionHelper):
         def __init__(self, callback: _CookieGenerateCallback) -> None:
             _CallbackExceptionHelper.__init__(self)
     
    +        max_cookie_len = getattr(_lib, "DTLS1_COOKIE_LENGTH", 255)
    +
             @wraps(callback)
             def wrapper(ssl, out, outlen):  # type: ignore[no-untyped-def]
                 try:
                     conn = Connection._reverse_mapping[ssl]
                     cookie = callback(conn)
    +                if len(cookie) > max_cookie_len:
    +                    raise ValueError(
    +                        f"Cookie too long (got {len(cookie)} bytes, "
    +                        f"max {max_cookie_len})"
    +                    )
                     out[0 : len(cookie)] = cookie
                     outlen[0] = len(cookie)
                     return 1
    
  • tests/test_ssl.py+38 0 modified
    @@ -5106,6 +5106,44 @@ def test_it_works_at_all(self) -> None:
         def test_it_works_with_srtp(self) -> None:
             self._test_handshake_and_data(srtp_profile=b"SRTP_AES128_CM_SHA1_80")
     
    +    def test_cookie_generate_too_long(self) -> None:
    +        s_ctx = Context(DTLS_METHOD)
    +
    +        def generate_cookie(ssl: Connection) -> bytes:
    +            return b"\x00" * 256
    +
    +        def verify_cookie(ssl: Connection, cookie: bytes) -> bool:
    +            return True
    +
    +        s_ctx.set_cookie_generate_callback(generate_cookie)
    +        s_ctx.set_cookie_verify_callback(verify_cookie)
    +        s_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem))
    +        s_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem))
    +        s_ctx.set_options(OP_NO_QUERY_MTU)
    +        s = Connection(s_ctx)
    +        s.set_accept_state()
    +
    +        c_ctx = Context(DTLS_METHOD)
    +        c_ctx.set_options(OP_NO_QUERY_MTU)
    +        c = Connection(c_ctx)
    +        c.set_connect_state()
    +
    +        c.set_ciphertext_mtu(1500)
    +        s.set_ciphertext_mtu(1500)
    +
    +        # Client sends ClientHello
    +        try:
    +            c.do_handshake()
    +        except SSL.WantReadError:
    +            pass
    +        chunk = c.bio_read(self.LARGE_BUFFER)
    +        s.bio_write(chunk)
    +
    +        # Server tries DTLSv1_listen, which triggers cookie generation.
    +        # The oversized cookie should raise ValueError.
    +        with pytest.raises(ValueError, match="Cookie too long"):
    +            s.DTLSv1_listen()
    +
         def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
             c_ctx = Context(DTLS_METHOD)
             c = Connection(c_ctx)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.