CVE-2024-11403 Overview
CVE-2024-11403 is an out-of-bounds read/write vulnerability in LibJXL, the reference implementation of the JPEG XL image format. The flaw resides in the JPEG decoder used by the JPEG XL encoder during JPEG recompression operations through the JxlEncoderAddJPEGFrame API. The decoder fails to properly check bounds when handling incomplete Huffman codes, which can lead to out-of-bounds writes. The same vulnerability is present in jpegli, released as part of the same project, where it can cause reads of uninitialized memory or function addresses. The issue is tracked as [CWE-125] (Out-of-bounds Read) and was fixed in commit 9cc451b91b74ba470fd72bd48c121e9f33d24c99.
Critical Impact
Processing untrusted JPEG input through the LibJXL encoder can trigger out-of-bounds memory access, potentially exposing function addresses or enabling memory corruption.
Affected Products
- libjxl_project libjxl (all versions prior to commit 9cc451b91b74ba470fd72bd48c121e9f33d24c99)
- jpegli (bundled in the same LibJXL project)
- Applications using JxlEncoderAddJPEGFrame on untrusted input
Discovery Timeline
- 2024-11-25 - CVE-2024-11403 published to NVD
- 2025-07-24 - Last updated in NVD database
Technical Details for CVE-2024-11403
Vulnerability Analysis
The vulnerability stems from an undersized Huffman lookup table in the JPEG decoding path. The original code defined kJpegHuffmanLutSize as 758 entries, based on the assumption that this size is sufficient for an alphabet of 257 symbols with a maximum bit length of 16 when the root table has 8 bits. This assumption holds only when the Huffman code is complete, which is verified by zlib/examples/enough.c.
When an attacker supplies a malformed JPEG with incomplete Huffman codes, the table can require more entries than allocated. This causes the decoder to write past the buffer end. In LibJXL's encoder path, this triggers a direct out-of-bounds write. In jpegli, the buffer is part of a larger structure, so the write corrupts adjacent fields, which the code later reads without validation.
Root Cause
The root cause is an incorrect size assumption for the Huffman lookup table. The fix increases kJpegHuffmanLutSize from 758 to 1024 entries to accommodate incomplete Huffman codes. The new size estimate accounts for the number of first-level cells, the number of symbols, and the asymptotic amount of repeated second-level cells (the sum 1 + 3 + ... + 255 representing maximum repetition in sub-tables).
Attack Vector
Exploitation requires an attacker to supply a crafted JPEG file as input to an application that invokes JxlEncoderAddJPEGFrame for JPEG recompression. User interaction and processing of untrusted content are required. The resulting out-of-bounds access may disclose function pointers or other memory contents, weakening Address Space Layout Randomization (ASLR) and aiding follow-on memory corruption attacks.
// Security patch in lib/jpegli/huffman.h and lib/jxl/jpeg/enc_jpeg_huffman_decode.h
// Port the Huffman lookup table size fix from brunsli (#3871)
constexpr int kJpegHuffmanRootTableBits = 8;
// Maximum huffman lookup table size.
// - According to zlib/examples/enough.c, 758 entries are always enough for
// - an alphabet of 257 symbols (256 + 1 special symbol for the all 1s code) and
// - max bit length 16 if the root table has 8 bits.
// - constexpr int kJpegHuffmanLutSize = 758;
// + Requirements: alphabet of 257 symbols (256 + 1 special symbol for the all 1s
// + code) and max bit length 16, the root table has 8 bits.
// + zlib/examples/enough.c works with an assumption that Huffman code is
// + "complete". Input JPEGs might have this assumption broken, hence the
// + following sum is used as estimate:
// + + number of 1-st level cells
// + + number of symbols
// + + asymptotic amount of repeated 2nd level cells
constexpr int kJpegHuffmanLutSize = 1024;
struct HuffmanTableEntry {
uint8_t bits; // number of bits used for this symbol
// ...
};
Source: LibJXL GitHub Commit 9cc451b
Detection Methods for CVE-2024-11403
Indicators of Compromise
- Crashes or abnormal terminations in processes linking against libjxl or jpegli when handling JPEG inputs
- Memory access violations reported by tools such as AddressSanitizer (ASan) during JPEG XL encoding workflows
- Unexpected output or corrupted data from JxlEncoderAddJPEGFrame operations on attacker-supplied images
Detection Strategies
- Inventory all applications and container images that bundle LibJXL or jpegli and verify their commit or release version against the patched commit 9cc451b91b74ba470fd72bd48c121e9f33d24c99
- Use Software Composition Analysis (SCA) tooling to flag vulnerable LibJXL builds in dependency manifests
- Run fuzz testing with corpora containing JPEGs that include incomplete Huffman codes against build pipelines that invoke JPEG XL recompression
Monitoring Recommendations
- Monitor image processing services for repeated crashes correlated with specific input files
- Log and retain JPEG inputs that trigger decoder errors for forensic review
- Alert on unexpected child process termination or core dumps in containers performing image conversion
How to Mitigate CVE-2024-11403
Immediate Actions Required
- Update LibJXL to a build that includes commit 9cc451b91b74ba470fd72bd48c121e9f33d24c99 or later
- Rebuild and redeploy any applications, libraries, and container images that statically link libjxl or jpegli
- Restrict use of JxlEncoderAddJPEGFrame to trusted inputs until patched binaries are deployed across the environment
Patch Information
The upstream fix is available in the LibJXL repository at commit 9cc451b91b74ba470fd72bd48c121e9f33d24c99. The patch increases kJpegHuffmanLutSize from 758 to 1024 in both lib/jpegli/huffman.h and lib/jxl/jpeg/enc_jpeg_huffman_decode.h. Refer to the LibJXL Security Commit for full details.
Workarounds
- Disable JPEG recompression features in applications that accept user-supplied images until patches are applied
- Sandbox JPEG XL encoder processes using seccomp, AppArmor, or container isolation to limit blast radius of memory corruption
- Validate JPEG inputs through a separate hardened decoder before passing them to JxlEncoderAddJPEGFrame
# Verify libjxl version includes the fix
git -C /path/to/libjxl log --oneline | grep 9cc451b
# Rebuild with the patched source
cd /path/to/libjxl
git fetch origin
git checkout 9cc451b91b74ba470fd72bd48c121e9f33d24c99
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --target jxl jpegli
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


