VYPR
High severityNVD Advisory· Published Nov 26, 2024· Updated Nov 26, 2024

ssrf vulnerability in lobe-chat

CVE-2024-32965

Description

Lobe Chat is an open-source, AI chat framework. Versions of lobe-chat prior to 1.19.13 have an unauthorized ssrf vulnerability. An attacker can construct malicious requests to cause SSRF without logging in, attack intranet services, and leak sensitive information. The jwt token header X-Lobe-Chat-Auth strored proxy address and OpenAI API Key, can be modified to scan an internal network in the target lobe-web environment. This issue has been addressed in release version 1.19.13 and all users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
@lobehub/chatnpm
< 1.19.131.19.13

Affected products

1

Patches

1
e960a23b0c69

🐛 fix: try to implement better ssrf-protect (#4044)

https://github.com/lobehub/lobe-chatArvin XuSep 20, 2024via ghsa
6 files changed · +24 38
  • package.json+1 0 modified
    @@ -203,6 +203,7 @@
         "remark": "^14.0.3",
         "remark-gfm": "^3.0.1",
         "remark-html": "^15.0.2",
    +    "request-filtering-agent": "^2.0.1",
         "resolve-accept-language": "^3.1.5",
         "rtl-detect": "^1.1.2",
         "semver": "^7.6.3",
    
  • src/app/api/proxy/route.ts+0 34 removed
    @@ -1,34 +0,0 @@
    -import { isPrivate } from 'ip';
    -import { NextResponse } from 'next/server';
    -import dns from 'node:dns';
    -import { promisify } from 'node:util';
    -
    -const lookupAsync = promisify(dns.lookup);
    -
    -export const runtime = 'nodejs';
    -
    -/**
    - * just for a proxy
    - */
    -export const POST = async (req: Request) => {
    -  const url = new URL(await req.text());
    -  let address;
    -
    -  try {
    -    const lookupResult = await lookupAsync(url.hostname);
    -    address = lookupResult.address;
    -  } catch (err) {
    -    console.error(`${url.hostname} DNS parser error:`, err);
    -
    -    return NextResponse.json({ error: 'DNS parser error' }, { status: 504 });
    -  }
    -
    -  const isInternalHost = isPrivate(address);
    -
    -  if (isInternalHost)
    -    return NextResponse.json({ error: 'Not support internal host proxy' }, { status: 400 });
    -
    -  const res = await fetch(url.toString());
    -
    -  return new Response(res.body, { headers: res.headers });
    -};
    
  • src/app/webapi/proxy/route.ts+19 0 added
    @@ -0,0 +1,19 @@
    +import { NextResponse } from 'next/server';
    +import fetch from 'node-fetch';
    +import { useAgent as ssrfAgent } from 'request-filtering-agent';
    +
    +/**
    + * just for a proxy
    + */
    +export const POST = async (req: Request) => {
    +  const url = await req.text();
    +
    +  try {
    +    const res = await fetch(url, { agent: ssrfAgent(url) });
    +
    +    return new Response(await res.arrayBuffer(), { headers: { ...res.headers } });
    +  } catch (err) {
    +    console.error(err); // DNS lookup 127.0.0.1(family:4, host:127.0.0.1.nip.io) is not allowed. Because, It is private IP address.
    +    return NextResponse.json({ error: 'Not support internal host proxy' }, { status: 400 });
    +  }
    +};
    
  • src/server/routers/lambda/user.ts+1 1 modified
    @@ -63,7 +63,7 @@ export const userRouter = router({
         const sessionCount = await sessionModel.count();
     
         return {
    -      canEnablePWAGuide: messageCount >= 2,
    +      canEnablePWAGuide: messageCount >= 4,
           canEnableTrace: messageCount >= 4,
           // 有消息,或者创建过助手,则认为有 conversation
           hasConversation: messageCount > 0 || sessionCount > 1,
    
  • src/services/_url.ts+2 2 modified
    @@ -1,4 +1,4 @@
    -// TODO: 未来路由需要迁移到 trpc or /webapi
    +// TODO: 未来所有核心路由需要迁移到 trpc,部分不需要迁移的则走 webapi
     
     /* eslint-disable sort-keys-fix/sort-keys-fix */
     import { transform } from 'lodash-es';
    @@ -17,7 +17,7 @@ const mapWithBasePath = <T extends object>(apis: T): T => {
     };
     
     export const API_ENDPOINTS = mapWithBasePath({
    -  proxy: '/api/proxy',
    +  proxy: '/webapi/proxy',
       oauth: '/api/auth',
     
       // agent markets
    
  • src/services/user/client.ts+1 1 modified
    @@ -23,7 +23,7 @@ export class ClientService implements IUserService {
     
         return {
           avatar: user.avatar,
    -      canEnablePWAGuide: messageCount >= 2,
    +      canEnablePWAGuide: messageCount >= 4,
           canEnableTrace: messageCount >= 4,
           hasConversation: messageCount > 0 || sessionCount > 0,
           isOnboard: true,
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.