CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-39892
6.9

CVE-2026-39892: Out-of-bounds Read in Python Cryptography via Non-Contiguous Buffers

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 9, 2026·6 min read·3 visits

PoC Available

Executive Summary (TL;DR)

An out-of-bounds read in Python's cryptography library allows attackers to cause denial of service or limited memory disclosure by providing non-contiguous buffer slices.

CVE-2026-39892 is a memory safety vulnerability within the Python cryptography package affecting versions 45.0.0 through 46.0.6. The flaw occurs due to improper handling of non-contiguous memory buffers passed through the Python Buffer Protocol, resulting in an out-of-bounds memory read when using Python 3.11 or later.

Vulnerability Overview

The cryptography package is a foundational Python library providing cryptographic primitives and recipes. CVE-2026-39892 represents an out-of-bounds read vulnerability within this library, classified under CWE-119. The defect manifests when specific memory-handling APIs process non-contiguous data structures.

The vulnerability affects cryptography versions 45.0.0 through 46.0.6 when running on Python versions greater than 3.11. The core issue resides in the library's interaction with the Python Buffer Protocol, which bridges high-level Python objects and low-level C or Rust implementations. Improper validation of buffer contiguity during these interactions leads directly to memory safety violations.

Exploitation of this flaw primarily affects system availability. An attacker supplying a maliciously crafted, non-contiguous buffer can force the library to read outside allocated memory bounds. This action typically results in a segmentation fault and process crash, though highly specific environmental conditions permit adjacent memory disclosure.

Root Cause Analysis

The Python Buffer Protocol (PEP 3118) allows C extensions and Rust bindings to access the internal memory of Python objects directly. This mechanism avoids unnecessary data copying and improves performance for cryptographic operations. Python objects like bytearray or memoryview expose a Py_buffer structure containing memory addresses, lengths, and layout descriptors.

Memory layouts are not always linear. Python permits non-contiguous buffers through slicing operations, such as strided slices or reversed slices. A reversed slice object retains the memory of the original structure but specifies negative strides to dictate a backward access pattern. The Py_buffer structure explicitly documents these strides so that consuming code can navigate the memory correctly.

The vulnerability occurs because the cryptography library implementation ignored the strides and is_contiguous properties of the provided Py_buffer. When presented with a reversed slice, the library extracted the base pointer, which points to the final byte of the original data segment. The implementation then executed a linear memory read equal to the buffer's length starting from that base pointer.

This linear read from the tail pointer bypasses the intended memory segment and traverses into adjacent, unrelated memory space. The severity is exacerbated in Python 3.11 and later due to internal modifications in memory view management and C-extension interactions. The resulting out-of-bounds read triggers an immediate violation of memory safety guarantees.

Code Analysis

Vulnerable implementations fail to verify memory layout properties before initiating data processing. The underlying Rust or C code assumes all incoming Py_buffer objects represent contiguous memory blocks. This assumption simplifies the memory parsing logic but violates the safety contracts defined by the Python Buffer Protocol.

In the vulnerable code path, the library extracts the buffer length and a data pointer without evaluating the associated stride metadata. The extraction function passes these raw attributes to low-level cryptographic primitives like the SHA256 update routine. The primitive then consumes bytes linearly, completely unaware that the data pointer originates from a reversed memory view.

The patched implementation introduces explicit contiguity validation. When an object is passed to APIs like Hash.update(), the library now strictly evaluates the is_contiguous property or inspects the buffer strides. If a non-contiguous buffer is detected, the library either rejects the input or safely forces a conversion to a contiguous block before processing.

Exploitation

Triggering this vulnerability requires the ability to pass a specifically formatted non-contiguous buffer to an affected API. The attacker must control the input structure fed to cryptographic functions such as Hash.update(). The exploitation process does not demand complex memory manipulation or heap grooming to achieve a denial-of-service condition.

The following proof-of-concept demonstrates the minimal code required to trigger the out-of-bounds read. The script creates a standard byte array and derives a reversed slice, generating a non-contiguous memory view. Passing this view to the SHA256 hashing primitive initiates the out-of-bounds memory access.

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.hashes import Hash, SHA256
 
buf = bytearray(b"A" * 32)
non_contiguous_buf = buf[::-1]
 
digest = Hash(SHA256())
digest.update(non_contiguous_buf)
print(digest.finalize().hex())

When executed on Python versions newer than 3.11, this script typically triggers a segmentation fault. The library reads past the end of the buf allocation into unmapped or restricted memory, causing the operating system to terminate the process. If the adjacent memory is mapped and readable, the hash output will incorporate unintended data, establishing a minor information disclosure primitive.

Impact Assessment

The vulnerability carries a CVSS v4.0 score of 6.9, reflecting a medium severity rating. The primary impact maps to the availability component of the CIA triad. The exploit complexity is strictly low, as triggering the defect requires no specialized access, authentication, or user interaction.

Denial of service represents the most immediate and reliable consequence of exploitation. Applications that accept user-provided data, slice it dynamically, and process the results via cryptography are vulnerable to remote crash capabilities. This risk is particularly relevant for networked services processing variable-length cryptographic payloads.

While the CVSS vector assigns a null score to confidentiality and integrity impacts, nuanced memory disclosure remains technically feasible. If the application environment maps readable memory directly adjacent to the manipulated buffer, the library will ingest this memory without crashing. The resulting cryptographic digest will reflect the contents of the leaked memory, requiring significant computational effort to extract raw values from a hashed output.

Remediation

Organizations must upgrade the cryptography package to version 46.0.7 or later to resolve this vulnerability entirely. This version implements proper buffer protocol validation and ensures that non-contiguous structures are handled safely. Package managers should target the >=46.0.7 version constraint during dependency resolution.

For environments where immediate patching is strictly prohibited, developers can implement a functional workaround. All buffers passed to cryptography APIs must be explicitly converted to contiguous byte objects prior to processing. Developers can achieve this by wrapping inputs in the standard bytes() or bytearray() constructors.

digest.update(bytes(non_contiguous_buf))

This explicit conversion forces Python to allocate a new, contiguous memory segment containing the correctly ordered data. The cryptography library then operates safely on this linear memory block. While this mitigation prevents the out-of-bounds read, it incurs a minor performance overhead due to the additional memory allocation and copying operations.

Official Patches

pycaOfficial GitHub Security Advisory
pycaCryptography v46.0.7 Changelog

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Affected Systems

pyca/cryptography package (versions 45.0.0 to 46.0.6)Python environments running version > 3.11

Affected Versions Detail

Product
Affected Versions
Fixed Version
cryptography
pyca
>= 45.0.0, < 46.0.746.0.7
AttributeDetail
CVE IDCVE-2026-39892
CVSS v4.06.9 (Medium)
CWE IDCWE-119
Attack VectorNetwork
Exploit StatusProof-of-Concept
CISA KEVNot Listed

MITRE ATT&CK Mapping

T1203Exploitation for Client Execution
Execution
T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-119
Improper Restriction of Operations within the Bounds of a Memory Buffer

Improper Restriction of Operations within the Bounds of a Memory Buffer

Known Exploits & Detection

Provided PoC ScriptPython snippet demonstrating how passing a reversed bytearray slice to Hash.update() triggers the memory violation.

Vulnerability Timeline

PyCA cryptography version 46.0.7 released
2026-04-07
oss-security advisory published
2026-04-08
CVE-2026-39892 assigned and published to NVD
2026-04-08

References & Sources

  • [1]GitHub Security Advisory GHSA-p423-j2cm-9vmq
  • [2]Cryptography Changelog
  • [3]OSS-Security Mailing List Announcement
  • [4]NVD Record for CVE-2026-39892

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.