CVE-2026-87961 Overview
CVE-2026-87961 is a heap-based out-of-bounds read vulnerability in the ESP32-audioI2S library, affecting versions 3.4.4 through 4.0.0. The flaw resides in the read_ID3_Header function, where a shadowed length parameter in ID3 synchronized-lyrics (SYLT) frame processing allows attackers to read past allocated buffer boundaries. Attackers deliver a malicious MP3 file or HTTP audio stream with an oversized frame size declaration to trigger the condition. Successful exploitation causes device crashes on the ESP32 microcontroller or exposes adjacent heap memory contents. The vulnerability is tracked under CWE-125: Out-of-Bounds Read.
Critical Impact
Remote attackers can crash ESP32-based audio devices or leak sensitive heap memory by delivering crafted MP3 files or HTTP audio streams containing malformed ID3 SYLT frames.
Affected Products
- ESP32-audioI2S version 3.4.4
- ESP32-audioI2S versions 3.5.x through 3.9.x
- ESP32-audioI2S version 4.0.0
Discovery Timeline
- 2026-09-10 - CVE-2026-87961 published to NVD
- 2026-09-10 - Last updated in NVD database
Technical Details for CVE-2026-87961
Vulnerability Analysis
The ESP32-audioI2S library parses ID3v2 metadata frames embedded in MP3 audio streams. Inside the read_ID3_Header function, the SYLT (synchronized lyrics) frame handler declares a local size_t len = 0 variable that shadows an outer length value used to gate buffer reads. When the code compares m_ID3Hdr.SYLT.size against this shadowed len (always zero), the guard fails to reject frames larger than the buffered data. The subsequent syltBuff.copy_from(data, m_ID3Hdr.SYLT.size) call reads m_ID3Hdr.framesize bytes from the source buffer regardless of how much valid audio data has been received. This produces an out-of-bounds read on the heap.
Root Cause
The root cause is a variable-shadowing bug combined with an inverted length check. The local len variable masks the intended length value, and the comparison m_ID3Hdr.SYLT.size < len evaluates against zero. Attackers control m_ID3Hdr.framesize through the ID3 frame header they supply, giving them direct control over the read length.
Attack Vector
Exploitation requires network delivery of a crafted MP3 file or HTTP audio stream and user interaction to initiate playback. The attacker sets an oversized framesize in the ID3v2 SYLT frame header, causing the parser to read beyond the audio buffer into adjacent heap memory. The primary impact is denial of service on the embedded device, with potential disclosure of heap contents adjacent to the audio buffer.
// Security patch in src/Audio.cpp — pull request #1381
ps_ptr<char> content_descriptor;
ps_ptr<char> syltBuff;
bool isBigEndian = true;
- size_t len = 0;
int idx = 0;
m_ID3Hdr.SYLT.pos = m_ID3Hdr.id3Size - m_ID3Hdr.remainingHeaderBytes;
m_ID3Hdr.SYLT.size = m_ID3Hdr.framesize;
- if (m_ID3Hdr.SYLT.size < len) return 0;
+ if (m_ID3Hdr.SYLT.size > len) return 0; // not enough data buffered yet, wait for more
syltBuff.copy_from(data, m_ID3Hdr.SYLT.size);
m_ID3Hdr.SYLT.text_encoding = syltBuff[0]; // 0=ISO-8859-1, 1=UTF-16, 2=UTF-16BE, 3=UTF-8
if (m_ID3Hdr.SYLT.text_encoding == 1) isBigEndian = false;
Source: GitHub Commit #4dc4614. The patch removes the shadowed len declaration and inverts the boundary check so undersized buffers cause the parser to wait for more data instead of over-reading.
Detection Methods for CVE-2026-87961
Indicators of Compromise
- Unexpected reboots or watchdog resets on ESP32 devices immediately after processing MP3 streams containing ID3v2 metadata.
- HTTP audio stream responses that contain ID3v2 SYLT frames with declared framesize values significantly larger than the actual payload.
- Crash dumps or serial log output showing faults inside read_ID3_Header or during syltBuff.copy_from operations.
Detection Strategies
- Inspect firmware images and application binaries for statically linked ESP32-audioI2S versions 3.4.4 through 4.0.0.
- Deploy network-layer inspection of HTTP audio streams delivered to IoT devices, flagging MP3 payloads with ID3v2 SYLT frames whose declared frame size exceeds the surrounding stream length.
- Correlate device crash telemetry with recent audio playback events sourced from external URLs.
Monitoring Recommendations
- Aggregate ESP32 serial and syslog output in a centralized logging pipeline to detect crash patterns tied to ID3 parsing.
- Track outbound requests from IoT devices to unusual audio streaming endpoints, since exploitation requires attacker-controlled content.
- Monitor firmware update inventories to confirm all deployed devices run patched ESP32-audioI2S releases beyond 4.0.0.
How to Mitigate CVE-2026-87961
Immediate Actions Required
- Identify all firmware projects that depend on ESP32-audioI2S versions 3.4.4 through 4.0.0 and schedule rebuilds against the patched source.
- Restrict ESP32 audio devices to trusted streaming sources by allow-listing URLs at the network gateway.
- Disable playback of MP3 files sourced from untrusted local storage or user uploads until firmware is updated.
Patch Information
The fix is available in commit 4dc4614, merged via Pull Request #1381. Rebuild firmware against a release incorporating this commit and reflash affected devices. Refer to the VulnCheck Security Advisory and GitHub Issue #1380 for additional technical context.
Workarounds
- Strip ID3v2 metadata from MP3 payloads at an upstream proxy before delivery to ESP32 devices.
- Block or filter HTTP audio streams originating from untrusted domains at the perimeter firewall.
- Constrain audio playback to a curated set of known-good MP3 files stored in signed firmware assets.
# Example: verify installed ESP32-audioI2S version in a PlatformIO project
grep -R "ESP32-audioI2S" platformio.ini lib/ | grep -i version
# Update the library dependency to a patched revision (post-commit 4dc4614)
pio pkg update -l "esphome/ESP32-audioI2S"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

