🔓 CVE-2025-54381 – ⚠️ Critical SSRF Vulnerability in BentoML Allows 🚨 Unauthorized Internal & Cloud Metadata Access
本指南旨在深入分析 BentoML 项目中的一个严重安全漏洞 (CVE-2025-54381)。我们将探讨其技术原理、潜在影响以及如何防范此类风险。
📛 漏洞信息
- CVE ID: CVE-2025-54381
- 公开日期: 2025年7月30日
- 发现者: Wiz Research Team
- 报告对象: GitHub Advisory Database & NVD
- 严重性: 严重 (Critical)
- CVSS v3.1 评分: 9.9 / 10
📦 受影响软件
- 产品: BentoML (一个用于打包、分发和部署机器学习模型的Python框架)
- 受影响版本:
- 从 1.4.0 到 1.4.19 (包含) 的所有版本
🔍 漏洞类型
- 类型: SSRF (服务端请求伪造,Server-Side Request Forgery)
- CWE 类别: CWE-918 – Server-Side Request Forgery
⚠️ 详细漏洞描述
该漏洞存在于 BentoML 模型服务API的基于URL的文件上传功能中。具体来说,BentoML 支持通过以下两种方式接收URL形式的文件输入:
- Multipart 表单请求
- JSON POST 请求
框架在处理这些请求时,会代表服务器端发起一个HTTP GET请求来下载用户提供的URL所指向的文件,但未能对用户提供的URL进行充分的验证。
为何危险?
攻击者可以诱骗服务器向以下目标发起请求,从而导致严重的安全问题:
- 访问仅限内部的服务,例如指向本地的
http://localhost:...或http://127.0.0.1:...。 - 访问云服务元数据端点,例如:
http://169.254.169.254/latest/meta-data/(AWS)http://metadata.google.internal/(GCP)
- 访问内部IP地址段的服务,例如:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
通过这些内部和云元数据端点,攻击者可能窃取到:
- IAM 凭据
- 访问令牌
- 服务密钥
- 内部API信息
- 管理后台面板
💣 影响范围
| 影响区域 | 描述 |
|---|---|
| 机密性 | 高 — 攻击者可能窃取内部秘密和凭据 |
| 完整性 | 低 — 该漏洞目前表现为只读攻击 |
| 可用性 | 中 — 可能通过请求大文件或慢服务造成DoS |
🛠️ 核心代码分析
以下是对漏洞相关代码逻辑的分析,展示了问题产生的根本原因。
1. URL 文件处理逻辑 (示例代码)
# 假设这是处理文件上传的简化代码
import requests
from flask import request
@app.route('/upload', methods=['POST'])
def upload_file():
# 从请求中获取文件来源,可能是直接上传的文件,也可能是一个URL
file_input = request.json.get('file')
# 漏洞点:如果输入看起来像一个URL,则直接发起请求获取内容
if file_input.startswith('http://') or file_input.startswith('https://'):
# 没有对URL的目标地址进行任何校验
response = requests.get(file_input) # SSRF漏洞发生在这里
file_content = response.content
# ... 后续处理文件内容
else:
# ... 处理直接上传的文件
pass
代码注释分析:
file_input = request.json.get('file'): 从用户控制的JSON请求体中获取file字段的值。if file_input.startswith(...): 简单地检查该值是否以http://或https://开头,以此判断是否为远程文件。requests.get(file_input): 关键风险点。直接使用用户提供的、未经验证的URL发起服务器端请求。攻击者可以将file_input设置为http://169.254.169.254/latest/meta-data/iam/security-credentials/等敏感内部地址,使服务器获取并返回这些敏感信息。
2. 更隐蔽的攻击载荷示例
# 攻击者可能使用重定向或编码技巧来绕过简单的检查
malicious_urls = [
"http://localtest.me/", # 解析到 127.0.0.1
"http://169.254.169.254/",
"http://metadata.google.internal/",
"http://[::1]/", # IPv6 本地回环地址
"http://0.0.0.0/", # 在某些系统上可能指向本地
"http://10.0.0.1/", # 内部私有IP
]
for url in malicious_urls:
# 如果服务器能访问这些地址,则存在漏洞
print(f"尝试访问: {url}")
# 假设服务器会像上面upload_file函数一样发起请求
# response = requests.get(url)
# print(response.text)
代码注释分析:
- 这个示例展示了攻击者可能尝试的各种URL,目标是探测和访问服务器内部网络资源。
localtest.me是一个通配符DNS域名,总是解析到127.0.0.1,常用于绕过基于域名黑名单的简单防护。- IPv6地址
[::1]和0.0.0.0也可能被利用来访问本地服务。 - 直接使用云服务商元数据IP和域名是获取云实例凭据的常见手法。
🔧 安装与版本检查指南
如果您正在使用BentoML,请立即检查您的版本。
系统要求
- Python 环境
- BentoML 包
检查BentoML版本
您可以通过以下命令检查当前环境中BentoML的版本:
pip show bentoml
或在Python脚本中检查:
import bentoml
print(bentoml.__version__)
受影响版本
如果您的版本在 1.4.0 到 1.4.19 (包含) 之间,则您的项目受到此漏洞影响。
解决方案
- 升级BentoML: 立即将BentoML升级到已修复此漏洞的最新版本(例如,1.4.20 或更高版本)。
pip install --upgrade bentoml - 临时缓解措施: 如果无法立即升级,应考虑在网络层面(如防火墙、Web应用防火墙WAF)阻断从BentoML服务实例发起的、指向内部网络和云元数据端点的出站请求。
📖 使用说明与安全建议
为了安全地使用BentoML并防范SSRF漏洞,开发者应遵循以下最佳实践:
- 严格验证用户输入: 对于任何用户提供的URL,都应进行严格的验证,包括:
- 协议白名单: 只允许
http和https,但也要谨慎对待。 - 域名/IP黑名单/白名单: 禁止访问内网IP段(如
127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16)和云元数据端点。 - DNS解析检查: 在发起请求前,先解析URL中的域名,检查其解析后的IP地址是否属于内网或黑名单范围。
- 协议白名单: 只允许
- 使用安全的HTTP客户端库: 配置HTTP客户端(如
requests库)以禁用重定向,或对重定向目标进行同样的验证。 - 最小权限原则: 运行BentoML服务的进程应使用最小必要的操作系统用户和权限,以限制攻击者通过SSRF漏洞所能造成的影响。
- 网络隔离: 将运行BentoML应用的服务器部署在严格隔离的网络环境中,通过防火墙策略限制其对外部和内部非必要服务的访问。FINISHED 6HFtX5dABrKlqXeO5PUv/84SoIo+TE3firf/5vX8AZ7hgh6Wp/6BeaOjelm1hXeB