vLLM: image EXIF Rotation & PNG tRNS Transparency Not Normalized, Causing Mismatch Between Model Input and Expectations
Medium4.8CVE-2026-12491 · Published Jun 17, 2026 · updated Sep 10, 2026
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| vllm PyPI | >= 0.11.0, < 0.24.0 | 0.24.0 |
Details and references
## Summary Issue 1: EXIF orientation not normalized → The image orientation processed by the model differs from how humans view it, introducing interpretation bias. Issue 2: PNG tRNS not explicitly flattened before converting to RGB → After conversion, transparent/semi-transparent pixels are rendered unexpectedly, making otherwise subtle overlay elements visible and distorting the input content. (This attack is similar to AlphaDog: RGBA handling is already correct in vLLM, but since tRNS permits RGB images, the correct processing path isn’t taken.) Issue 3 : Pillow only loads the first frame when loading APNG or GIF files. --- ## Root Cause * **Rotation**: After opening an image, `ImageOps.exif_transpose` is not called to normalize EXIF orientation. * **Transparency**: Only **RGBA→RGB** is flattened with a background; PNGs carrying **`tRNS`** in **`P`/`L`/`RGB + tRNS`** and other non-RGBA modes take the `image.convert("RGB")` path, which implicitly discards/remaps transparency semantics. --- ## Affected Code https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L77-L84 https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L37-L43 https://github.com/vllm-project/vllm/blob/16b37f3119918c1e5a39f303e0d0892c65c07a90/vllm/multimodal/image.py#L26-L34 > Current state: `ImageOps.exif_transpose` is not used. (Although the `rescale_image_size` function ([https://github.com/vllm-project/vllm/blob/main/vllm/multimodal/image.py#L14](https://github.com/vllm-project/vllm/blob/main/vllm/multimodal/image.py#L14)) exists and includes a `transpose` parameter, I’ve found that it doesn’t seem to be called anywhere outside the `test` directory.) > **Call order**: `_convert_image_mode` runs first; if the conditions are met, `convert_image_mode` is called. > > **Issue**: Only the “RGBA → RGB” path is explicitly flattened. `P`, `L`, or `RGB` with `tRNS` all fall back to `image.convert("RGB")`. For PNGs that include `tRNS`, `convert("RGB")` directly produces 24-bit RGB, leading to: > > * **`P` mode**: The transparent index becomes an actual RGB color (often black, white, or an undefined background), so transparency is lost. > * **`L/LA` and `RGB + tRNS`**: `convert("RGB")` doesn’t composite against a chosen background first, so elements that relied on transparency to be hidden or softened become solid. ## Impact & Scope * **Impact**: Pixels the model sees can diverge from operator expectations (due to orientation or transparency handling), potentially altering downstream reasoning. * **Scope**: The image I/O and mode-conversion paths in `vllm/multimodal/image.py`. The existing **RGBA→RGB** flattening is correct; the issues center on **missing EXIF normalization** and **non-RGBA `tRNS` not being explicitly composited**. ## Case EXIF: http://qiniu.funxingzuo.top/exif_orient_180.jpg tRNS: http://qiniu.funxingzuo.top/hello.png ## Fix A fix for this vulnerability was merged here: https://github.com/vllm-project/vllm/pull/44974
- CVSS 3.1
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:L
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-436
- Also known as
- CVE-2026-12491, PYSEC-2026-3406
- github.com/vllm-project/vllm/security/advisories/GHSA-8jr5-v98p-w75m
- nvd.nist.gov/vuln/detail/CVE-2026-12491
- github.com/vllm-project/vllm/pull/44974
- github.com/vllm-project/vllm/commit/cf1c90672404548aa3bc51f92c4745576a65ee26
- access.redhat.com/security/cve/CVE-2026-12491
- bugzilla.redhat.com/show_bug.cgi?id=2489786
- github.com/advisories/GHSA-8jr5-v98p-w75m
- github.com/pypa/advisory-database/tree/main/vulns/vllm/PYSEC-2026-3406.yaml
- github.com/vllm-project/vllm
- pypi.org/project/vllm
More vLLM advisories
All vLLM| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jun 16 | vLLM: OpenAI auth bypass CVE-2026-48746Critical9.1fixed in 0.22.0 | Critical9.1 | 0.22.0 |
| Jun 16 | vLLM: Security Check Bypass via assert Statement in Activation Function Loading Allows Arbitrary Code Execution CVE-2026-41523High7.5fixed in 0.22.0 | High7.5 | 0.22.0 |
| Jun 17 | vLLM: temperature=NaN and temperature=Infinity bypass validation and propagate to GPU kernels CVE-2026-54235Medium6.5fixed in 0.24.0 | Medium6.5 | 0.24.0 |
| Jun 17 | vLLM: GGUF dequantize kernel int truncation exposes uninitialized GPU memory in multi-tenant serving CVE-2026-53923Medium7.5fixed in 0.24.0 | Medium7.5 | 0.24.0 |
| Jun 17 | vLLM: incomplete CVE-2026-22778 fix leaks PIL repr addresses via Anthropic router CVE-2026-54236Medium5.3fixed in 0.24.0 | Medium5.3 | 0.24.0 |
| Jun 17 | vLLM: OOM Denial of Service via Audio Decompression Bomb CVE-2026-54233Medium6.5fixed in 0.24.0 | Medium6.5 | 0.24.0 |