
Authenticated SSRF via raw fetch bypassing ssrf-safe-fetch (skill import and generation cover)
快速结论:此报错发生在 LobeChat 自部署环境中,当认证用户通过技能导入(Skill Import)或主题封面生成(Generation Topic Cover)端点提供内部 URL 时,服务器会使用原生 fetch 而非 ssrfSafeFetch 发起请求,导致 SSRF 漏洞。优先排查 src/server/services/skill/importer.ts 和 src/server/services/generation/index.ts 中的 fetch 调用是否替换为 ssrfSafeFetch。
问题场景
用户在 LobeChat(版本 2.2.1,Docker 自部署,Linux)中,通过认证用户身份调用 tRPC 端点 agentSkills.importFromUrl 或 generationTopic.updateTopicCover 时,服务器使用全局 fetch 而非内置的 packages/ssrf-safe-fetch 防护模块,导致可对内网主机和云元数据端点进行 SSRF 攻击。
报错原文
// 在技能导入中,无 SSRF 防护的 fetch 调用:
response = await fetch(input.url, { signal: controller.signal }); // raw global fetch, no SSRF guard
// 在主题封面生成中,无 SSRF 防护的 fetch 调用:
const response = await fetch(url, { headers: fetchHeaders }); // raw global fetch, no SSRF guard
// 攻击示例:通过技能导入读取云元数据
POST /trpc/lambda/agentSkills.importFromUrl
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
// 攻击示例:通过封面更新进行图像 SSRF
POST /trpc/lambda/generationTopic.updateTopicCover
{ "id": "", "coverUrl": "http://127.0.0.1:6379/" }
原因分析
LobeChat 内置了反 SSRF 辅助模块 packages/ssrf-safe-fetch,该模块通过 request-filtering-agent 在 socket 连接时阻止私有和链路本地地址,并在每次重定向时重新检查。然而,两个经过认证的 tRPC 端点(技能导入和主题封面生成)使用了全局 fetch 而非该防护模块,导致认证用户可以强制服务器请求任意内部主机或云元数据端点。在技能导入场景下,响应体被存储并返回给调用者,形成完全读取的 SSRF;在封面生成场景下,图像类型响应可被读取并存储,非图像响应则为盲 SSRF 并泄漏状态码/状态文本。
注意:代码中 web-crawler 和 imageUrlToBase64 助手函数已正确使用了 ssrfSafeFetch,证实这两个调用路径是遗漏。
环境排查
- 确认 LobeChat 版本是否为 2.2.1(Issue 中报告版本)或更早版本。
- 确认部署方式是否为 Docker 自部署(Self-hosting Docker),且未使用反向代理做额外 SSRF 防护。
- 确认是否已安装
packages/ssrf-safe-fetch模块(位于项目packages/ssrf-safe-fetch/index.ts)。
解决步骤
- 确认 Issue 已关闭,修复合并在 #16601 中。
- 升级 LobeChat 至包含修复的版本(例如 2.2.2 或更高,具体检查发布说明)。
- 如果无法立即升级,可回退步骤:
- 手动检查
src/server/services/skill/importer.ts文件,将fetch替换为ssrfSafeFetch导入和调用。 - 手动检查
src/server/services/generation/index.ts文件中的fetchImageFromUrl函数,同样替换为ssrfSafeFetch。 - 验证更新后代码中不再存在直接使用全局
fetch处理用户提供 URL 的路径。
验证方法
在升级或修复后,使用以下测试验证:
以认证用户身份发送 POST /trpc/lambda/agentSkills.importFromUrl 请求,提供内网地址(如 http://169.254.169.254/latest/meta-data/),确认请求被阻止且返回 SSRF 相关错误,而非返回内部数据。同样测试 POST /trpc/lambda/generationTopic.updateTopicCover 使用内部 URL,确认服务器不会发起请求到私有地址。
另外检查 packages/ssrf-safe-fetch 的日志或调用链,确认所有 fetch 请求都经过该模块。
参考来源
关联修复 PR:#16601
原安全公告:GHSA-53h9-fmjf-frwr(2026-06-04 提交)


