SSRF Protection Bypass in vLLM
Description
vLLM is an inference and serving engine for large language models (LLMs). The SSRF protection fix for CVE-2026-24779 add in 0.15.1 can be bypassed in the load_from_url_async method due to inconsistent URL parsing behavior between the validation layer and the actual HTTP client. The SSRF fix uses urllib3.util.parse_url() to validate and extract the hostname from user-provided URLs. However, load_from_url_async uses aiohttp for making the actual HTTP requests, and aiohttp internally uses the yarl library for URL parsing. This vulnerability in 0.17.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vllmPyPI | >= 0.15.1, < 0.17.0 | 0.17.0 |
Affected products
1Patches
16f3b2047abd4[Core] Fix SSRF bypass via backslash-@ URL parsing inconsistency (#34743)
2 files changed · +59 −2
tests/multimodal/media/test_connector.py+57 −0 modified@@ -7,8 +7,10 @@ import os from tempfile import NamedTemporaryFile, TemporaryDirectory +import aiohttp import numpy as np import pytest +import requests import torch from PIL import Image, ImageChops @@ -318,3 +320,58 @@ async def test_allowed_media_domains(video_url: str, num_frames: int): with pytest.raises(ValueError): _, _ = await connector.fetch_video_async(disallowed_url) + + +@pytest.mark.asyncio +async def test_ssrf_bypass_backslash_in_url(local_asset_server): + """Verify that backslash-@ URL parsing confusion cannot bypass the + allowed_media_domains check (GHSA-v359-jj2v-j536). + + urllib3.parse_url() and aiohttp/yarl disagree on how to parse a + backslash before ``@``. urllib3 treats ``\\`` as part of the path + (encoding it as ``%5C``), while yarl treats it as a userinfo + separator, changing the effective host. The fix normalises the URL + through urllib3 *before* handing it to aiohttp so both layers agree. + """ + port = local_asset_server.port + asset = TEST_IMAGE_ASSETS[0] + + # Craft the bypass payload: urllib3 sees host=127.0.0.1, but an + # un-patched aiohttp would see host=example.com. + bypass_url = f"http://127.0.0.1:{port}\\@example.com/{asset}" + + connector = MediaConnector( + allowed_media_domains=["127.0.0.1"], + ) + + # After the fix the request is made to 127.0.0.1 (the local asset + # server) using the normalised URL. The normalised path will be + # /%5C@example.com/<asset> which won't match any file the server + # knows about, so we expect an HTTP error — but crucially NOT a + # successful fetch from example.com. + with pytest.raises(requests.exceptions.HTTPError): + connector.fetch_image(bypass_url) + + with pytest.raises(aiohttp.ClientResponseError): + await connector.fetch_image_async(bypass_url) + + +@pytest.mark.asyncio +async def test_ssrf_bypass_backslash_disallowed_domain(): + """The reverse direction: even when the *attacker-controlled* host + appears in the urllib3-parsed hostname position the allowlist must + still block it. + """ + # urllib3.parse_url sees host=example.com which is NOT in the + # allowlist, so this must be rejected before any request is made. + bypass_url = "https://example.com\\@safe.example.org/image.png" + + connector = MediaConnector( + allowed_media_domains=["safe.example.org"], + ) + + with pytest.raises(ValueError, match="allowed domains"): + connector.fetch_image(bypass_url) + + with pytest.raises(ValueError, match="allowed domains"): + await connector.fetch_image_async(bypass_url)
vllm/multimodal/media/connector.py+2 −2 modified@@ -146,7 +146,7 @@ def load_from_url( connection = self.connection data = connection.get_bytes( - url, + url_spec.url, timeout=fetch_timeout, allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS, ) @@ -177,7 +177,7 @@ async def load_from_url_async( connection = self.connection data = await connection.async_get_bytes( - url, + url_spec.url, timeout=fetch_timeout, allow_redirects=envs.VLLM_MEDIA_URL_ALLOW_REDIRECTS, )
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-v359-jj2v-j536ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-25960ghsaADVISORY
- github.com/vllm-project/vllm/commit/6f3b2047abd4a748e3db4a68543f8221358002c0ghsax_refsource_MISCWEB
- github.com/vllm-project/vllm/pull/34743ghsax_refsource_MISCWEB
- github.com/vllm-project/vllm/security/advisories/GHSA-qh4c-xf7m-gxfcghsax_refsource_MISCWEB
- github.com/vllm-project/vllm/security/advisories/GHSA-v359-jj2v-j536ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.