OPENEXR · CVE-2026-34543 · Package
FIX → 3.4.8 +2
OpenEXR's PXR24 decoder accepts a truncated compressed stream and reads uninitialized heap memory into the output pixel data. Opening a malicious EXR file can leak sensitive heap contents into the decoded image.
first public Mar 27, 2026 · 2 sources
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Any application that uses the Python OpenEXR bindings to read EXR files that may come from untrusted sources, such as upload pipelines, asset services or image previewers. The flaw is in the PXR24 decompression path, so pipelines that only handle other EXR compression modes or only write trusted files are less exposed. Projects that never read untrusted EXR input can skip it.
Not affected if no-pxr24-files, trusted-input-only
Who cares image-processing, openexr, pypi, python
The PXR24 decompression function undo_pxr24_impl in OpenEXR (internal_pxr24.c) ignores the actual decompressed size (outSize) returned by exr_uncompress_buffer() and instead reads from the scratch buffer based solely on the expected size (uncompressed_size) derived from the header metadata.
Additionally, exr_uncompress_buffer() (compression.c:202) treats LIBDEFLATE_SHORT_OUTPUT (where the compressed stream decompresses to fewer bytes than expected) as a successful result rather than an error.
When these two issues are combined, an attacker can craft a PXR24 EXR file containing a valid but truncated zlib stream. As a result, the decoder reads uninitialized heap memory and incorporates it into the output pixel data.
This issue occurs due to the combination of two flaws.
else if (res == LIBDEFLATE_SHORT_OUTPUT)
{
/* TODO: is this an error? */
return EXR_ERR_SUCCESS;
}
libdeflate_zlib_decompress_ex() returns LIBDEFLATE_SHORT_OUTPUT when the compressed stream is successfully decompressed but the resulting output size is smaller than the provided output buffer size. In this case, the actual number of decompressed bytes is written to actual_out. However, the function does not treat this condition as an error and instead returns success.
rstat = (
decode->context, compressed_data, comp_buf_size,
scratch_data, scratch_size, &outSize);
if (rstat != EXR_ERR_SUCCESS) return rstat;
for (int y = ; y < decode->chunk.height; ++y) { ... }
<img width="858" height="155" alt="스크린샷 2026-03-15 오후 4 38 18" src="https://github.com/user-attachments/assets/ded9eab6-9b92-40f7-9a0d-7b00db7e6088" />
Are you affected?
Tell InfraStack what you run. It checks this one, and every next one, against your stack.
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
pip show openexropenexr in requirements.txt, pyproject.toml or a lock fileUpgrade to 3.4.8 +2
openexr (pypi) 3.4.8 for the 3.4.x line, per the fixed version in the product dataAfter exr_uncompress_buffer() returns success, the code does not verify whether the actual decompressed size (outSize) matches the expected size (uncompressed_size). The subsequent byte-plane reconstruction loop reads from the scratch buffer up to uncompressed_size bytes. As a result, the region between outSize and uncompressed_size consists of uninitialized heap memory, which is then read by the decoder.
Affected component
Please refer to the atta poc.zip ched archive file and proceed after extracting it.
This page as .md · .json · CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
GitHub Advisory Database, CC-BY 4.0 · NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.