CVE-2026-107389
music-metadata: EBML parser trusts element lengths, allowing memory exhaustion or process abort
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the Matroska and WebM EBML parser decodes an attacker-controlled VINT element length and uses it for string-token or Uint8Array allocation before confirming that the leaf fits within its parent or available input. Crafted WebM, MKV, or MKA inputs can cause disproportionate allocations, out-of-memory denial of service, or, for a demonstrated parseFile path on Node.js 26.7.0, an uncatchable V8 fatal abort. The exact failure mode depends on the tokenizer, parser API, and runtime, but the affected leaf-length validation flaw is shared and has availability impact only. This issue is fixed in version 11.16.0.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
6.2
music-metadata: EBML parser trusts element lengths, allowing memory exhaustion or process abort
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the Matroska and WebM EBML parser decodes an attacker-controlled VINT element length and uses it for string-token or Uint8Array allocation before confirming that the leaf fits within its parent or available input. Crafted WebM, MKV, or MKA inputs can cause disproportionate allocations, out-of-memory denial of service, or, for a demonstrated parseFile path on Node.js 26.7.0, an uncatchable V8 fatal abort. The exact failure mode depends on the tokenizer, parser API, and runtime, but the affected leaf-length validation flaw is shared and has availability impact only. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107389- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
EUVDEUVD-2026-95238
6.2
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the Matroska and WebM EBML parser decodes an attacker-controlled VINT element length and uses it for string-token or Uint8Array allocation before confirming that the leaf fits within its parent or available input. Crafted WebM, MKV, or MKA inputs can cause disproportionate allocations, out-of-memory denial of service, or, for a demonstrated parseFile path on Node.js 26.7.0, an uncatchable V8 fatal abort. The exact failure mode depends on the tokenizer, parser API, and runtime, but the affected leaf-length validation flaw is shared and has availability impact only. This issue is fixed in version 11.16.0.
- Record
EUVD-2026-95238- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-5gfj-9q3v-qfp3
6.2
music-metadata: EBML parser trusts element lengths, allowing memory exhaustion or process abort
Summary
The Matroska/WebM EBML parser decodes attacker-controlled variable-length integer (VINT) element lengths without first validating that the declared element fits within its enclosing container or the available input. Leaf lengths are then used directly for string-token and Uint8Array allocations.
A very small crafted .webm, .mkv, or .mka file can therefore cause a disproportionately large allocation, an out-of-memory denial of service, or—in one demonstrated parseFile case—an uncatchable V8 fatal abort.
Impact
Applications that parse untrusted Matroska/WebM media can be denied service. Depending on the input, parser API, and Node.js/V8 version, the demonstrated outcomes include:
- a 34-byte input causing an approximately 128 MiB allocation before end-of-input;
- a 70-byte input causing a 500 MiB allocation through a binary EBML leaf, with concurrent parses multiplying memory consumption;
- a 48-byte file causing an uncatchable V8 fatal abort through
parseFilewhen a leaf declares a length of 32 GiB.
The fatal-abort case was reproduced on music-metadata 11.15.0 with Node.js 26.7.0. It was deterministic across three runs and exited with code 133 despite a surrounding try/catch. The same reporter did not reproduce that fatal abort through parseBuffer on Node.js 20 through 25; those configurations can still encounter allocation attempts or catchable errors. The exact failure mode is therefore runtime- and tokenizer-dependent, but the underlying validation flaw is shared.
The impact is limited to availability; no confidentiality or integrity impact has been demonstrated.
Root cause
EbmlIterator.readElement() decodes an element length from an EBML VINT and converts it to a JavaScript Number:
private async readElement(): Promise<IHeader> {
const id = await this.readVintData(this.ebmlMaxIDLength);
const lenField = await this.readVintData(this.ebmlMaxSizeLength);
lenField[0] ^= 0x80 >> (lenField.length - 1);
return {
id: readUIntBE(id, id.length),
len: readUIntBE(lenField, lenField.length)
};
}
Before the fix, that value was not checked against the parent boundary or known file size before reaching the leaf readers:
private async readString(e: IHeader): Promise<string> {
const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
return rawString.replace(/\x00.*$/g, '');
}
private async readBuffer(e: IHeader): Promise<Uint8Array> {
const buf = new Uint8Array(e.len);
await this.tokenizer.readBuffer(buf);
return buf;
}
An EBML size VINT can encode values approaching 2^56. A crafted file can select a known string, unsigned-integer, binary, or UID element and route its declared size into an allocation before the tokenizer discovers that the input is truncated. The declared length also participates in container-boundary arithmetic.
For lengths around 32 GiB, one reporter observed V8 aborting on its external-memory accounting check:
Fatal error: Check failed: change_in_bytes < kMaxReasonableBytes
process exit code 133
This is a V8 process abort rather than a JavaScript exception, so application-level error handling cannot catch it.
Attack scenarios
The issue is reachable through ordinary metadata parsing of attacker-controlled Matroska/WebM files. Reported proofs of concept exercised string, unsigned-integer, binary, and UID leaves. Depending on the tokenizer and runtime, affected entry points include parseBuffer, parseFile, parseStream, parseBlob, and parseWebStream.
One minimal buffer-based proof of concept uses a docType string with an oversized eight-byte VINT:
import { parseBuffer } from 'music-metadata';
const payload = Uint8Array.from([
0x1a, 0x45, 0xdf, 0xa3, 0x8a,
0x42, 0x82,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
]);
await parseBuffer(payload, { mimeType: 'video/webm' });
Another proof of concept used a valid WebM EBML header followed by an…
- Record
GHSA-5gfj-9q3v-qfp3- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
NVD
6.2
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the Matroska and WebM EBML parser decodes an attacker-controlled VINT element length and uses it for string-token or Uint8Array allocation before confirming that the leaf fits within its parent or available input. Crafted WebM, MKV, or MKA inputs can cause disproportionate allocations, out-of-memory denial of service, or, for a demonstrated parseFile path on Node.js 26.7.0, an uncatchable V8 fatal abort. The exact failure mode depends on the tokenizer, parser API, and runtime, but the affected leaf-length validation flaw is shared and has availability impact only. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107389- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
OSV
6.2
music-metadata: EBML parser trusts element lengths, allowing memory exhaustion or process abort
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the Matroska and WebM EBML parser decodes an attacker-controlled VINT element length and uses it for string-token or Uint8Array allocation before confirming that the leaf fits within its parent or available input. Crafted WebM, MKV, or MKA inputs can cause disproportionate allocations, out-of-memory denial of service, or, for a demonstrated parseFile path on Node.js 26.7.0, an uncatchable V8 fatal abort. The exact failure mode depends on the tokenizer, parser API, and runtime, but the affected leaf-length validation flaw is shared and has availability impact only. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107389- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
OSVGHSA-5gfj-9q3v-qfp3
6.2
music-metadata: EBML parser trusts element lengths, allowing memory exhaustion or process abort
Summary
The Matroska/WebM EBML parser decodes attacker-controlled variable-length integer (VINT) element lengths without first validating that the declared element fits within its enclosing container or the available input. Leaf lengths are then used directly for string-token and Uint8Array allocations.
A very small crafted .webm, .mkv, or .mka file can therefore cause a disproportionately large allocation, an out-of-memory denial of service, or—in one demonstrated parseFile case—an uncatchable V8 fatal abort.
Impact
Applications that parse untrusted Matroska/WebM media can be denied service. Depending on the input, parser API, and Node.js/V8 version, the demonstrated outcomes include:
- a 34-byte input causing an approximately 128 MiB allocation before end-of-input;
- a 70-byte input causing a 500 MiB allocation through a binary EBML leaf, with concurrent parses multiplying memory consumption;
- a 48-byte file causing an uncatchable V8 fatal abort through
parseFilewhen a leaf declares a length of 32 GiB.
The fatal-abort case was reproduced on music-metadata 11.15.0 with Node.js 26.7.0. It was deterministic across three runs and exited with code 133 despite a surrounding try/catch. The same reporter did not reproduce that fatal abort through parseBuffer on Node.js 20 through 25; those configurations can still encounter allocation attempts or catchable errors. The exact failure mode is therefore runtime- and tokenizer-dependent, but the underlying validation flaw is shared.
The impact is limited to availability; no confidentiality or integrity impact has been demonstrated.
Root cause
EbmlIterator.readElement() decodes an element length from an EBML VINT and converts it to a JavaScript Number:
private async readElement(): Promise<IHeader> {
const id = await this.readVintData(this.ebmlMaxIDLength);
const lenField = await this.readVintData(this.ebmlMaxSizeLength);
lenField[0] ^= 0x80 >> (lenField.length - 1);
return {
id: readUIntBE(id, id.length),
len: readUIntBE(lenField, lenField.length)
};
}
Before the fix, that value was not checked against the parent boundary or known file size before reaching the leaf readers:
private async readString(e: IHeader): Promise<string> {
const rawString = await this.tokenizer.readToken(new StringType(e.len, 'utf-8'));
return rawString.replace(/\x00.*$/g, '');
}
private async readBuffer(e: IHeader): Promise<Uint8Array> {
const buf = new Uint8Array(e.len);
await this.tokenizer.readBuffer(buf);
return buf;
}
An EBML size VINT can encode values approaching 2^56. A crafted file can select a known string, unsigned-integer, binary, or UID element and route its declared size into an allocation before the tokenizer discovers that the input is truncated. The declared length also participates in container-boundary arithmetic.
For lengths around 32 GiB, one reporter observed V8 aborting on its external-memory accounting check:
Fatal error: Check failed: change_in_bytes < kMaxReasonableBytes
process exit code 133
This is a V8 process abort rather than a JavaScript exception, so application-level error handling cannot catch it.
Attack scenarios
The issue is reachable through ordinary metadata parsing of attacker-controlled Matroska/WebM files. Reported proofs of concept exercised string, unsigned-integer, binary, and UID leaves. Depending on the tokenizer and runtime, affected entry points include parseBuffer, parseFile, parseStream, parseBlob, and parseWebStream.
One minimal buffer-based proof of concept uses a docType string with an oversized eight-byte VINT:
import { parseBuffer } from 'music-metadata';
const payload = Uint8Array.from([
0x1a, 0x45, 0xdf, 0xa3, 0x8a,
0x42, 0x82,
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
]);
await parseBuffer(payload, { mimeType: 'video/webm' });
Another proof of concept used a valid WebM EBML header followed by an…
- Record
GHSA-5gfj-9q3v-qfp3- CVSS 3.1
- 6.2 Medium
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-789
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
music-metadatanpm |
before 11.16.0 | 11.16.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107389 is a medium vulnerability (CVSS 6.2) in Borewit Music-metadata, published October 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.21%, the 11th percentile. Fixed in music-metadata 11.16.0.
References
github.com/Borewit/music-metadata/security/advisories/GHSA-5gfj-9q3v-qfp3
github.com/Borewit/music-metadata/pull/2735
github.com/Borewit/music-metadata/commit/163f013364ac9fc8dd0c3987433cd065a615af58
github.com/Borewit/music-metadata/commit/2d14dc1f7391a94235948a0b823155538f69b3df
github.com/Borewit/music-metadata/releases/tag/v11.16.0
github.com/advisories/GHSA-5gfj-9q3v-qfp3
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107389.json
nvd.nist.gov/vuln/detail/CVE-2026-107389
github.com/Borewit/music-metadata
Left out here: the rest of 2 source descriptions. The JSON record has them.