Oct 8, 2026·7 min read·7 visits
A regression in the MP4 stsd parser of music-metadata allows unauthenticated local or remote attackers to trigger a synchronous infinite loop and memory exhaustion via a crafted media file, blocking the Node.js event loop.
An input validation vulnerability exists in music-metadata versions prior to 11.16.0, where parsing a crafted MP4 file containing a sample-description (stsd) box with a zero-value size entry causes a synchronous infinite loop and memory exhaustion, resulting in complete Denial of Service.
The music-metadata package is a popular open-source audio and video metadata parser designed for Node.js and browser runtimes. It is widely incorporated into file-processing pipelines, content management systems, and media upload interfaces. Because it handles arbitrary binary streams from untrusted users, its parsing logic represents a critical surface area for security threats.
During development iterations on the master branch prior to release 11.16.0, a regression was introduced in the parser for MP4 stsd (sample description) boxes. The parsing logic is synchronous, which presents specific risks within the Node.js execution environment.
When music-metadata parses a maliciously structured MP4 file containing an entry with a declared size of zero, the internal file offset pointer fails to advance. The parsing loop continues indefinitely because its termination condition depends on an attacker-controlled entry counter. This infinite loop blocks the single-threaded Node.js event loop, preventing all concurrent execution and resulting in a denial of service.
The root cause of this vulnerability lies in lib/mp4/AtomToken.ts within the StsdAtom.get() method. A regression was introduced during modifications designed to align the offset progress calculation with the size fields of individual sample description entries. To compensate for the 4 bytes read during the size field extraction, the offset progress logic was updated from off += size to off += size - 4.
Under normal execution, the variable size represents the size of the current sample entry table, which must be at least 16 bytes. However, the input validation fails to verify that size is greater than or equal to the minimum required structure length before performing arithmetic on the pointer.
If the size field of an entry is explicitly set to 0 inside an attacker-controlled MP4 file, the math evaluates as follows:
off is incremented by 4 bytes (Token.UINT32_BE.len) to account for reading the size field.size - 4. Since size is 0, the program calculates 0 - 4 = -4.4 + (-4) = 0.Consequently, the pointer remains fixed on the exact same buffer location. In the next iteration of the loop, the parser reads the same zero value, calculates the same net zero progress, and remains stuck. Since the loop termination is bound by the attacker-specified numberOfEntries counter (which can be defined up to 4294967295), the execution hangs indefinitely.
The vulnerability is demonstrated in the execution logic within StsdAtom.get(). The following block represents the vulnerable execution path:
// Vulnerable loop structure in lib/mp4/AtomToken.ts
for (let n = 0; n < header.numberOfEntries; ++n) {
const size = Token.UINT32_BE.get(buf, off); // Reads 0 from attacker-controlled buffer
off += Token.UINT32_BE.len; // off increments by 4
// Inserts a new table instance based on the non-advanced offset
table.push(new SampleDescriptionTable(size - Token.UINT32_BE.len).get(buf, off));
off += size - Token.UINT32_BE.len; // off evaluates to: off + (0 - 4), net change is 0
}Because the net progress of the pointer is zero, the loop iterates endlessly, reading the exact same index. In each iteration, table.push(...) is evaluated. This continuously appends elements to the internal array, causing unbounded heap memory growth until the system runs out of memory (OOM).
The fix implemented in version 11.16.0 addresses this by applying strict boundary validations. The size of each entry is now validated against the minimum physical length of an MP4 SampleEntry (16 bytes) and checked to ensure it does not exceed the remaining buffer length:
// Patched logic in lib/mp4/AtomToken.ts
const end = Math.min(off + this.len, buf.length);
if (end - off < stsdHeader.len) {
throw new Mp4ContentError('Truncated stsd header');
}
const header = stsdHeader.get(buf, off);
off += stsdHeader.len;
const table: ISampleDescription[] = [];
for (let n = 0; n < header.numberOfEntries; ++n) {
if (end - off < Token.UINT32_BE.len) {
throw new Mp4ContentError('Truncated stsd sample entry');
}
const size = Token.UINT32_BE.get(buf, off);
// Enforce absolute minimum entry size boundary of 16 bytes
if (size < 16 || size > end - off) {
throw new Mp4ContentError(`Invalid stsd sample entry size: ${size}`);
}
off += Token.UINT32_BE.len;
table.push(new SampleDescriptionTable(size - Token.UINT32_BE.len).get(buf, off));
off += size - Token.UINT32_BE.len;
}By ensuring that size is at least 16, the loop is guaranteed to advance off by at least 12 bytes on each pass, preventing any freeze and constraining the absolute maximum execution iterations by the physical file size.
Exploitation of this vulnerability requires delivering a malformed MP4-family file (such as .mp4, .m4a, or .3gp) to an application that processes the file with an unpatched version of music-metadata.
The attack vector is local or remote, depending on where the host application processes files. In a common application scenario, a user uploads a media file to an API endpoint which then reads the metadata on the backend server. The attacker generates a minimal valid MP4 container consisting of basic headers and a corrupted stsd atom.
The structure of the exploit payload relies on key structures:
ftyp box to bypass primitive format detection filters.stsd box that contains a numberOfEntries property set to a high limit, such as 0xFFFFFFFF.0x00000000.When the system receives the payload, the main Node.js event loop executes the parsing logic synchronously. Because Node.js is single-threaded, the entire process freezes. No concurrent network requests can be processed, and no microtasks or timers can execute. This blocks all application functionality for users sharing that process.
The overall security impact of this vulnerability is high, and it is classified as a severe Endpoint Denial of Service (T1499). While the attack does not allow privilege escalation or direct data leakage, its operational impact on Node.js-based services is complete.
Because of the single-threaded nature of Node.js, a synchronous infinite loop halts all event loop operations. Any other active requests are left unanswered, and the application becomes unresponsive. This allows a single unauthenticated HTTP request containing a small, 48-byte malicious file to completely disable a server instance.
Additionally, because each loop iteration instantiates and pushes a new SampleDescriptionTable object onto the local table array, the system dynamically consumes heap space. This results in rapid memory consumption, culminating in an Out Of Memory (OOM) error that terminates the Node.js process entirely, requiring a system restart.
The primary recommendation is to update the music-metadata dependency to version 11.16.0 or higher, which integrates the correct boundary checks.
For environments where immediate upgrading is not possible, the following defensive practices should be adopted:
Isolate Processing Pipelines: Run file metadata parsing tasks inside isolated Worker Threads (worker_threads module) or within sandbox subprocesses. This ensures that if a thread encounters an infinite loop or crashes from memory exhaustion, the main application remains responsive.
Configure Process-Level Hard Limits: Employ process supervisors like PM2 or systemd to monitor CPU usage thresholds and memory footprints. Configure these managers to automatically recycle workers that exceed maximum expected runtimes or memory limits.
Request Timeouts: Ensure that reverse proxies, load balancers, and gateway servers enforce strict timeouts on upload processing endpoints to prevent resources from being held indefinitely by locked processes.
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
music-metadata Borewit | < 11.16.0 | 11.16.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-835 / CWE-400 |
| Attack Vector | Local (AV:L) |
| CVSS v3.1 Score | 6.2 (Medium) |
| Exploit Status | PoC Validated |
| Impact | Denial of Service (DoS) and Memory Exhaustion (OOM) |
| KEV Status | Not Listed |
The program contains an iteration loop with an exit condition that cannot be met, causing it to run indefinitely.
CVE-2026-61427 is a critical authentication bypass and improper input validation vulnerability within the Model Context Protocol (MCP) HTTP-stream server of PraisonAI. In versions prior to 4.6.78, the server lacks authentication by default and forwards client messages directly to Python tool handlers without input validation. When bound to non-localhost interfaces, this permits unauthenticated remote attackers to perform unauthorized administrative operations and execute tools.
CVE-2026-107387 is a high-impact uncontrolled memory allocation vulnerability in music-metadata, a widely used Node.js metadata parser. The flaw occurs in the APEv2 tag parser, where the library reads an attacker-controlled 32-bit integer indicating the tag size and immediately requests a corresponding heap buffer reservation. Because this allocation occurs before validating if the input stream actually contains those bytes, an attacker can supply a minuscule audio file to trigger large, disproportionate allocations, resulting in heap exhaustion and an uncatchable process-wide Out of Memory (OOM) crash.
A path traversal vulnerability in datamodel-code-generator allows remote attackers to write or overwrite arbitrary files on the local host filesystem via a manipulated Protobuf schema containing malicious weak import paths.
PraisonAI is vulnerable to an arbitrary local file read vulnerability prior to version 4.6.78. The flaw is in the ContextGatherer component, where validation checks are executed only after files are parsed and appended to the context bundle, bypassing security constraints.
An algorithmic complexity vulnerability (CWE-770) in the Excelize library allows remote attackers to cause resource exhaustion (100% CPU usage) via a crafted Microsoft Excel spreadsheet. This occurs because the look-ahead row index parsing in Rows.Columns() fails to enforce upper boundary limits, enabling an out-of-bounds row index to trigger an infinite seek loop inside the Rows iterator.
An unauthenticated Server-Side Request Forgery (SSRF) vulnerability exists in Ghost CMS from version 6.54.1 to 6.65.0. The vulnerability stems from a validation bypass in the favicon resolution logic within the bookmark-fetching subsystem, which allows remote, unauthenticated attackers to trigger arbitrary HTTP requests to the local host and internal networks. This bypass circumvents the custom DNS-level IP blocklist controls configured globally in the application.