Memory-exhaustion DoS in BMP decoder (bundled bmp-ts dependency) via unbounded width/height
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 62/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- node.js, typescript
- Ambito
- security
Direzione di ricerca
Inizia da plugins/js-bmp/src/index.ts e dai percorsi di allocazione e riempimento di decoder.js di bmp-ts incluso, descritti nel report. Esegui la riproduzione BMP fornita e appositamente creata con Jimp.read() per stabilire il comportamento della crescita della memoria, quindi aggiungi una copertura per rifiutare le dimensioni eccessive prima dell'allocazione. Il lavoro è completato quando la riproduzione viene rifiutata senza eseguire la grande allocazione e la normale decodifica BMP continua a funzionare.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
@jimp/js-bmp delegates BMP decoding entirely to the bmp-ts npm package with no validation of its own. bmp-ts's decoder allocates its output pixel buffer directly from the BMP header's width/height fields with no upper bound and no comparison against the actual input size:
// [email protected] dist/commonjs/decoder.js:153
this.data = Buffer.alloc(this.width * this.height * 4);
For RLE4/RLE8-compressed BMPs, the very next thing that happens is:
// decoder.js:201 (bit4) and :279 (bit8)
this.data.fill(0);
Buffer.fill() forces real physical memory to be committed across the whole buffer (unlike Buffer.alloc's lazily-zero-mapped pages), and this happens before any actual pixel bytes are read from the file, so a tiny file with a big declared width/height is enough to force a large real memory allocation.
Proof of Concept
A crafted 1078-byte BMP (valid BM magic + 40-byte BITMAPINFOHEADER, bitPP=8, compression=1 i.e. BI_RLE8, width=10000, height=10000, a 256-entry zero palette, and no actual RLE pixel data after the palette) causes roughly 405MB of RSS growth in a single Jimp.read() call, confirmed against the real published [email protected] (which bundles [email protected]):
input size 1078 bytes rss before ~67.7MB
Jimp.read(buffer) -> eventually throws RangeError (only AFTER the .fill(0) commits memory)
time 278ms rss after ~472.4MB (~405MB forced commit from a 1KB file)
Scaling width/height further is unbounded — nothing in bmp-ts or in @jimp/js-bmp's wrapper (plugins/js-bmp/src/index.ts, which calls BMP.decode() directly with no width/height sanity check before delegating) caps the allocation. A handful of concurrent uploads of ~1KB crafted files could force multi-GB memory growth or an allocator OOM in any service that calls Jimp.read() on user-uploaded images (a very common pattern — avatar/image upload handling).
This is a memory-exhaustion availability issue (CWE-400/789), not memory corruption — Node's Buffer/TypedArray bounds checks prevent any actual out-of-bounds read/write.
Suggested Fix
Before allocating the output buffer, validate that width * height * bytesPerPixel is consistent with the actual input buffer size (or with a reasonable configurable maximum), and reject the file early if not. This applies both in bmp-ts's decoder.js (root cause) and as a defense-in-depth check in @jimp/js-bmp's wrapper before it delegates to bmp-ts, since jimp is the package most people actually depend on directly.
Disclosure note
Checked for existing reports first: no GHSA/CVE/OSV advisory exists for bmp-ts, jimp, or @jimp/js-bmp. Neither repo has SECURITY.md or GitHub private vulnerability reporting enabled, so filing this as a plain public issue rather than a private advisory — severity is DoS-only (not RCE/memory-corruption), so this seemed reasonable to disclose directly; happy to move to a private channel if one gets set up.
- Lingua principale
- TypeScript
- Stelle
- 14.7k
- Fork
- 777
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di jimp-dev/jimp
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
-
Add blit changes to migration guide.Forse già presa @ryanchou1994 l’ha presa 45 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
documentation help wanted solution in issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 48/100
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
Tutte le issue di jimp-dev/jimp
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
NousResearch/hermes-agent#147433 ·
I maintainer di solito rispondono entro 1 giorno
-
needs-triage🔍
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
Dokploy/dokploy#5836 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement tech debt
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
ehmpathy/rhachet-roles-bhrain#739 ·
I maintainer di solito rispondono entro 1 giorno