Hi,
On Fri, 18 Sep 2026 16:57:13 -0700 Alan Coopersmith <[email protected]> wrote: > https://heif-heist.com/ seems more promotional than informational at > this point, but it does point out there are a number of exploitable > vulnerabilities in "native C/C++ decoders such as libheif and > libde265". Not sure if related, but this very recent commit https://github.com/strukturag/libheif/commit/6ce2bba558a27b63a508e81c085025f91c89899b sounds like it could be security-related and it is not part of the 1.23.4 release. Copying over commit description: --------- Reject in-band coded image sizes over the security limit for all codecs (GHSA-v8qw-hwjv-44hw) A crafted image can declare a small size in its container 'ispe' property while its bitstream declares a much larger coded frame. The container-level checks are based on 'ispe', so the oversized bitstream was handed to the decoder, which allocated a buffer for the in-band size before libheif rejected the mismatch. The advisory demonstrated this for AV1 with the libaom backend (a ~351-byte AVIF declaring 64x64 but coding 8192x8192..27648x27648, allocating hundreds of MB to >10 GB), but the same class affects every codec whose real frame size lives in the bitstream rather than in the container. Enforce the coded size in the codec-independent decode path, before any bytes reach a decoder plugin, so the fix is both codec- and backend-independent (it protects the ffmpeg backend too, which does no size check of its own): - Rename the per-decoder hook get_coded_image_size_from_config() to get_max_coded_image_size(const std::vector<uint8_t>&). The old name no longer described the behaviour: it now scans the whole bitstream, not just the configuration record. It is an internal method with a single caller. - decode_sequence_frame_from_compressed_data() now fetches the compressed data once and passes that same buffer to both the size gate and the decoder push, so the combined config+bitstream buffer is not built twice per decode. - AV1/AVIF: scan every OBU_SEQUENCE_HEADER in the combined configOBUs + item data for the largest max_frame_width/height (new find_max_av1_frame_size_in_stream()). - AVC/HEVC/VVC: scan every SPS NAL unit in the combined config + item data (new split_nal_units_4byte_length_prefixed()), not just the SPS in avcC/hvcC/vvcC, since an SPS carried in the item data also drives the decoder's allocation. Return the largest coded (pre-crop) size. - JPEG: parse the SOF marker dimensions (previously discarded) and gate on them. - JPEG 2000 / HTJ2K: parse the SIZ reference grid (Xsiz, Ysiz) from the codestream. This makes the check backend-independent; the OpenJPEG plugin's own grid gate (GHSA-q492-cfcm-895h) remains as a backstop. Uncompressed images are libheif's own decoder and are sized from the container, so they are not in this class. Add regression tests: tests/inband_coded_size_limit.cc (the advisory AV1 PoC plus HEVC/AVC/JPEG in-band attack files) and tests/nal_split.cc (NAL splitter edge cases). -- Hanno Böck - Independent security researcher https://itsec.hboeck.de/ https://badkeys.info/
