vllm: Nemotron-VL processors disable Pillow decompression-bomb guard globally, enabling unauthenticated DoS
What fixes it
No source in this snapshot names a fixed version.
Description
Summary
vllm/transformers_utils/processors/nemotron_vl.py and nano_nemotron_vl.py each set Image.MAX_IMAGE_PIXELS = None at module load time, permanently disabling Pillow's process-global decompression-bomb defence. An unauthenticated caller who can reach /v1/chat/completions on a vLLM instance that has imported either Nemotron-VL processor can submit a pathological image that decompresses into substantial memory, potentially OOM-killing the worker and denying service to co-tenants. The report was confirmed on vLLM 0.8.5.
Details
Both processor modules set Image.MAX_IMAGE_PIXELS = None unconditionally at import time. The module-level side effect disables Pillow's guard for every Image.open() call for the lifetime of that process.
MediaConnector.load_from_url hands image bytes to ImageMediaIO.load_bytes, which opens and decodes the image. With MAX_IMAGE_PIXELS set to None, Pillow's decompression-bomb limit is disabled for this path.
The issue was tested on vLLM 0.8.5 / commit feffb51d3f; the same sink was observed on main at 1a096d8208.
Impact
A deployment serving a Nemotron-VL model, or one that imports either processor, can be exposed to memory exhaustion through attacker-controlled image input. Since the setting is process-global, unrelated image loads in the same process are affected too. CWE-400 (Uncontrolled Resource Consumption).
Fix
PR #47010 removes both module-level Image.MAX_IMAGE_PIXELS = None assignments. It also adds a decoded pixel-count limit in the shared image loader, configurable through VLLM_MAX_IMAGE_PIXELS.
Text from GitHub Advisory Database
Affected versions 1
- vllm, pip<= 0.8.5GitHub