---
id: "GHSA-9g3c-x747-c6wr"
page: "https://infrastack.ai/live/GHSA-9g3c-x747-c6wr"
kind: "vulnerability"
aliases: ["GHSA-9g3c-x747-c6wr"]
title: "Quadratic Cohere2 Vision preprocessing DoS via request-controlled max_patches"
severity: "medium"
cvss: null
epss: null
exploited: false
status: "open"
category: "ai-tooling"
products: [{"name": "vllm", "fixed": ["0.31.0"], "affected": ">= 0.10.1, < 0.31.0", "ecosystem": "pypi"}]
ecosystems: ["pypi"]
tags: ["ai-tooling", "cwe-400", "cwe-407", "llm-serving", "python", "self-hosted", "vllm"]
not_affected_if: ["api-auth-with-trusted-clients", "no-cohere2-vision-model", "version-0.31.0-or-later"]
published_at: "2026-10-27T22:20:43+00:00"
first_seen_at: "2026-11-09T22:53:23+00:00"
updated_at: "2026-11-09T22:58:55+00:00"
sources: [{"source": "ghsa-repo", "url": "https://github.com/vllm-project/vllm/security/advisories/GHSA-9g3c-x747-c6wr", "first_seen_at": "2026-11-09T22:53:23+00:00"}]
exploit_sources: []
---

# Quadratic Cohere2 Vision preprocessing DoS via request-controlled max_patches

Link for people: https://infrastack.ai/live/GHSA-9g3c-x747-c6wr (this .md is for agents)

A client sending an image chat request to vLLM serving a Cohere2 Vision model can set mm_processor_kwargs.max_patches to a large value, forcing quadratic CPU work during preprocessing. This lets an attacker slow or deny service to other clients, with no code execution or data exposure demonstrated.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- pypi:vllm affected >= 0.10.1, < 0.31.0 fixed 0.31.0

## How to check

- Check the installed vLLM version with `pip show vllm` or `python -c "import vllm; print(vllm.__version__)"`; versions from `>= 0.10.1` and below `0.31.0` are affected.
- Check whether the server is serving a Cohere2 Vision model through the OpenAI-compatible server.
- Check whether the server accepts per-request `mm_processor_kwargs` from untrusted clients; the advisory says `--trust-request-mm-kwargs` should stay disabled for them.

## Fix

- Upgrade `vllm` to `0.31.0` or later.
- Keep `--trust-request-mm-kwargs` disabled for untrusted clients (per PR #58830, untrusted per-request `mm_processor_kwargs` are blocked by default).

## Timeline

- 2026-11-09T22:53:23+00:00 ghsa-repo https://github.com/vllm-project/vllm/security/advisories/GHSA-9g3c-x747-c6wr

## Documents

- [advisory] Maintainer's advisory: github.com https://github.com/vllm-project/vllm/security/advisories/GHSA-9g3c-x747-c6wr

## From the sources

## Summary

The Python OpenAI-compatible server accepts a request-controlled
`mm_processor_kwargs.max_patches` value when serving Cohere2 Vision models.
vLLM forwards the value to the Hugging Face processor without applying a
server-side upper bound. The processor enumerates candidate tile aspect ratios
with two loops whose bounds are both controlled by `max_patches`, causing
quadratic CPU work before normal inference limits can protect the service.

A client that can access the chat-completions endpoint can submit a small,
valid image together with a large `max_patches` value. Varying the value across
requests also avoids reuse of the helper's small LRU cache. This can occupy
multimodal preprocessing workers, substantially increase request latency, and
deny service to other clients.

No code execution, confidentiality impact, or integrity impact was
demonstrated.

## Confirmed Affected Revision

The issue was rechecked on 2026-09-08 against the then-current upstream
`main` commit:

```text
f6326f53bda46898a331c2d24500332c285d9a2b
```

Commit permalink:
https://github.com/vllm-project/vllm/commit/f6326f53bda46898a331c2d24500332c285d9a2b

The original audited revision was:

```text
7ca49fbe4bab019e55d57cdc4b7fd3d55c67c1a6
```

The vulnerable data flow was present at the revision assessed in this report.

## Why This Is a Security Issue

`max_patches` is a computational budget, but the Python serving path lets a
remote request choose it. The expensive enumeration occurs during request
preprocessing, before the request reaches normal model execution. A small
request body can therefore trigger work disproportionate to its size.

The default server does not require an API key. If an operator configures API
authentication, exploitation instead requires a client authorized to call the
affected endpoint.

## Pre-requisites

- vLLM is serving a Cohere2 Vision model through the Python OpenAI-compatible
  frontend.
- The caller can submit an image chat request.
- The request supplies a large positive integer as
  `mm_processor_kwargs.max_patches`.

No special build flag, remote model code, malformed image, or unsafe runtime
option is required. The issue is model-specific and is not a claim that every
vLLM deployment is affected.

## Technical Details

The request-to-sink chain at the confirmed revision is:

1. `ChatCompletionRequest.mm_processor_kwargs` is an unrestricted
   `dict[str, Any]`:
   https://github.com/vllm-project/vllm/blob/f6326f53bda46898a331c2d24500332c285d9a2b/vllm/entrypoints/openai/chat_completion/protocol.py#L372-L375
2. `OnlineRenderer.preprocess_chat` copies the request value into both the chat
   parameters and prompt extras:
   https://github.com/vllm-project/vllm/blob/f6326f53bda46898a331c2d24500332c285d9a2b/vllm/renderers/online_renderer.py#L675-L704
3. `BaseRenderer` applies the extras and constructs `MMProcessorInputs` with
   the same processor kwargs:
   https://github.com/vllm-project/vllm/blob/f6326f53bda46898a331c2d24500332c285d9a2b/vllm/renderers/base.py#L769-L779
   https://github.com/vllm-project/vllm/blob/f6326f53bda46898a331c2d24500332c285d9a2b/vllm/renderers/base.py#L846-L880
4. `Cohere2VisionProcessingInfo.get_num_patches` passes the merged mapping to
   `get_number_of_image_patches` without bounding `max_patches`:
   https://github.com/vllm-project/vllm/blob/f6326f53bda46898a331c2d24500332c285d9a2b/vllm/model_executor/models/cohere2_vision.py#L170-L188
5. In Transformers 5.16.1, `get_number_of_image_patches` reads
   `max_patches` from that mapping and calls `get_optimal_tiled_canvas`:
   https://github.com/huggingface/transformers/blob/v5.16.1/src/transformers/models/cohere2_vision/image_processing_cohere2_vision.py#L257-L285
6. The aspect-ratio helper loops from 1 through the attacker-selected value in
   both dimensions:
   https://github.com/huggingface/transformers/blob/v5.16.1/src/transformers/models/cohere2_vision/image_processing_cohere2_vision.py#L53-L80

The relevant operation is equivalent to:

```python
for width in range(1, max_image_tiles + 1):
    for height in range(1, max_image_tiles + 1):
        if width * height <= max_image_tiles:
            aspect_ratios.append((width, height))
```

The nested loops perform Theta(`max_patches` squared) iterations. The helper
has an LRU cache of only ten argument values, so requests using distinct large
values continue to force cold computations.

## Expected Result

Request-level processor overrides must not be able to raise a server-owned
preprocessing budget beyond a safe configured limit. An excessive value should
be rejected before invoking the Hugging Face processor.

## Security Impact

A remote or API-authorized caller can consume disproportionate CPU time in the
multimodal preprocessing path. Repeated cold computations can delay image
requests and reduce or deny availability for other clients. The demonstrated
impact is limited to availability.

## Severity Assessment

- Severity: Moderate
- CWE-407: Inefficient Algorithmic Complexity
- CWE-400: Uncontrolled Resource Consumption
- CVSS v3.1: 5.3
- Vector: `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L`

`PR:N` reflects the default server configuration without an API key. An
authenticated deployment changes the required access conditions, and the vLLM
team should assign the final severity and version range.

## Duplicate Search

On 2026-09-08, public vLLM issues, pull requests, and published GitHub Security
Advisories were searched using combinations of `max_patches`, `Cohere2
Vision`, `get_all_supported_aspect_ratios`, `mm_processor_kwargs`, `quadratic`,
and `denial of service`. No public report with this specific model, request
parameter, and root cause was found.

Private vulnerability reports are not searchable, so this does not rule out a
private duplicate.

## Suggested Remediation

- Treat the server/model configuration as the authority for the maximum
  permitted patch count.
- Reject request-level `max_patches` values that are not strict positive
  integers or that exceed that server-owned limit.
- Apply the validation to both flat and modality-scoped processor kwargs where
  supported.
- Add tests proving that an oversized value is rejected before Cohere2 Vision
  preprocessing and that safe values continue to work.
- Consider improving the upstream Transformers enumeration independently, but
  do not rely on that optimization as the request-boundary security control.

## Disclosure Coordination

Please handle this report through vLLM's private vulnerability-reporting
workflow. No public issue or pull request has been created for this finding.
The reporter can provide additional source traces or help validate a proposed
fix. Public disclosure and any public remediation pull request should follow
the maintainers' triage and coordination guidance.

## Affected versions

- Package: `vllm` (PyPI).
- Affected versions: `>= 0.10.1, < 0.31.0`.
- First stable patched version: `0.31.0`.

PR #58830 blocks untrusted per-request `mm_processor_kwargs` and `media_io_kwargs` by default before preprocessing. Keep `--trust-request-mm-kwargs` disabled for untrusted clients. Explicitly enabling it restores trusted override behavior; the underlying processor/sampler is not independently bounded by this fix.

Advisory fixed in [#58830](https://github.com/vllm-project/vllm/pull/58830).

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
