Authenticated SSRF via raw fetch bypassing ssrf-safe-fetch (skill import and generation cover)

用户在 LobeChat(版本 2.2.1,Docker 自部署,Linux)中,通过认证用户身份调用 tRPC 端点 agentSkills.importFromUrl 或 generationTopic.updateTopicCover 时,服务器使用全局 fetch 而非内置的 package

Authenticated SSRF via raw fetch bypassing ssrf-safe-fetch (skill import and generation cover)

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.tssrc/server/services/generation/index.ts 中的 fetch 调用是否替换为 ssrfSafeFetch

问题场景

用户在 LobeChat(版本 2.2.1,Docker 自部署,Linux)中,通过认证用户身份调用 tRPC 端点 agentSkills.importFromUrlgenerationTopic.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-crawlerimageUrlToBase64 助手函数已正确使用了 ssrfSafeFetch,证实这两个调用路径是遗漏。

环境排查

  • 确认 LobeChat 版本是否为 2.2.1(Issue 中报告版本)或更早版本。
  • 确认部署方式是否为 Docker 自部署(Self-hosting Docker),且未使用反向代理做额外 SSRF 防护。
  • 确认是否已安装 packages/ssrf-safe-fetch 模块(位于项目 packages/ssrf-safe-fetch/index.ts)。

解决步骤

  1. 确认 Issue 已关闭,修复合并在 #16601 中。
  2. 升级 LobeChat 至包含修复的版本(例如 2.2.2 或更高,具体检查发布说明)。
  3. 如果无法立即升级,可回退步骤:
  4. 手动检查 src/server/services/skill/importer.ts 文件,将 fetch 替换为 ssrfSafeFetch 导入和调用。
  5. 手动检查 src/server/services/generation/index.ts 文件中的 fetchImageFromUrl 函数,同样替换为 ssrfSafeFetch
  6. 验证更新后代码中不再存在直接使用全局 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 请求都经过该模块。

参考来源

lobehub/lobe-chat #16536

关联修复 PR:#16601

原安全公告:GHSA-53h9-fmjf-frwr(2026-06-04 提交)

celebrityanime
celebrityanime
文章: 10915

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注