ghsa-fgx4-p8xf-qhp9
Vulnerability from github
Vulnerability Description
Vulnerability Overview
-
When the client sends an arbitrary URL array and impl: ["naive"] to the tRPC endpoint tools.search.crawlPages, the server issues outbound HTTP requests directly to those URLs. There is no defensive logic that restricts or validates requests to internal networks (127.0.0.1, localhost, private ranges) or metadata endpoints (169.254.169.254).
-
Flow: client input (urls, impls) → service invocation in the tRPC router → the service passes the URLs to Crawler.crawl → the Crawler prioritizes the user-specified impls (naive) → the naive implementation performs a server-side fetch(url) as-is (SSRF) → the server collects responses from internal resources.
-
In the dev environment, authentication can be bypassed using the lobe-auth-dev-backend-api: 1 header (production requires a valid token). In the PoC, this was used to successfully retrieve the internal API at localhost:8889 from the server side.
Vulnerable Code
https://github.com/lobehub/lobe-chat/blob/d942a635b36a231156c60d824afa573af8032572/packages/web-crawler/src/crawImpl/naive.ts#L39-L45
PoC
PoC Description
-
In dev mode, we made a single tRPC call using the auth-bypass header lobe-auth-dev-backend-api: 1. Since tRPC requires the body to be in the form {"json": { ... }}, we placed urls and impls: ["naive"] inside json to induce the server to request the internal URL (http://localhost:8889/internel-api).
-
The response follows tRPC’s wrapping structure, so the actual body of the internal API is included as a string (JSON string) at result.data.json.results[0].data.content. We post-process it with jq for readability.
curl Example
bash
curl -sS -X POST 'http://localhost:3010/trpc/tools/search.crawlPages' \
-H 'Content-Type: application/json' \
-H 'lobe-auth-dev-backend-api: 1' \
--data '{"json":{"urls":["http://localhost:8889/internal-api"],"impls":["naive"]}}' | jq -r '.result.data.json.results[0].data.content' | jq .
Impact
-
Since the server performs outbound requests to internal networks, localhost, and metadata endpoints, an attacker can abuse the server’s network position to access internal resources (internal APIs, management ports, cloud metadata, etc.).
-
As a result, this can lead to exposure of internal system information, leakage of authentication tokens/secret keys (e.g., IMDSv1/v2), misuse of internal admin interfaces, and provide a foothold for further lateral movement.
-
By leveraging user-supplied impls to force the unfiltered naive implementation, SSRF defenses—such as blocking private/metadata IPs, DNS re-validation/re-resolution, and redirect restrictions—can be bypassed.
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 1.136.1"
},
"package": {
"ecosystem": "npm",
"name": "@lobehub/chat"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "1.136.2"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-62505"
],
"database_specific": {
"cwe_ids": [
"CWE-918"
],
"github_reviewed": true,
"github_reviewed_at": "2025-10-17T17:46:09Z",
"nvd_published_at": "2025-10-17T19:15:38Z",
"severity": "LOW"
},
"details": "### Vulnerability Description\n---\n\nVulnerability Overview\n \n- When\u00a0the client sends an arbitrary\u00a0URL\u00a0array and\u00a0impl:\u00a0[\"naive\"]\u00a0to the tRPC endpoint\u00a0tools.search.crawlPages, the server\u00a0issues outbound HTTP requests\u00a0directly to those URLs. There is no\u00a0defensive logic that restricts or validates requests to internal networks (127.0.0.1, localhost, private ranges) or\u00a0metadata endpoints (169.254.169.254).\n\n- Flow: client input (urls,\u00a0impls) \u2192 service\u00a0invocation in the tRPC router\u00a0\u2192 the service passes the URLs\u00a0to\u00a0Crawler.crawl\u00a0\u2192 the\u00a0Crawler\u00a0prioritizes the user-specified\u00a0impls\u00a0(naive)\u00a0\u2192 the\u00a0naive\u00a0implementation performs a server-side\u00a0fetch(url)\u00a0as-is\u00a0(SSRF) \u2192 the\u00a0server collects responses from\u00a0internal resources.\n\n- In the\u00a0dev environment, authentication can\u00a0be bypassed using the\u00a0lobe-auth-dev-backend-api: 1\u00a0header (production\u00a0requires a valid\u00a0token). In the PoC, this was used to successfully retrieve\u00a0the internal API at\u00a0localhost:8889\u00a0from the server side.\n\nVulnerable\u00a0Code\n \n\nhttps://github.com/lobehub/lobe-chat/blob/d942a635b36a231156c60d824afa573af8032572/packages/web-crawler/src/crawImpl/naive.ts#L39-L45\n\n\n### PoC\n---\n\nPoC Description\n\n- In\u00a0dev\u00a0mode, we made a single tRPC call using the auth-bypass header\u00a0lobe-auth-dev-backend-api: 1. Since tRPC requires the\u00a0body to\u00a0be\u00a0in the form\u00a0{\"json\": {\u00a0... }}, we\u00a0placed\u00a0urls\u00a0and\u00a0impls: [\"naive\"]\u00a0inside\u00a0json\u00a0to\u00a0induce the\u00a0server to\u00a0request the\u00a0internal URL\u00a0(http://localhost:8889/internel-api).\n\n- The\u00a0response follows\u00a0tRPC\u2019s wrapping\u00a0structure, so\u00a0the actual body\u00a0of\u00a0the internal\u00a0API is\u00a0included\u00a0as a\u00a0string\u00a0(JSON string) at\u00a0result.data.json.results[0].data.content. We\u00a0post-process\u00a0it\u00a0with\u00a0jq\u00a0for\u00a0readability.\n\ncurl Example \n\n```bash\ncurl -sS -X POST \u0027http://localhost:3010/trpc/tools/search.crawlPages\u0027 \\\n -H \u0027Content-Type: application/json\u0027 \\\n -H \u0027lobe-auth-dev-backend-api: 1\u0027 \\\n --data \u0027{\"json\":{\"urls\":[\"http://localhost:8889/internal-api\"],\"impls\":[\"naive\"]}}\u0027 | jq -r \u0027.result.data.json.results[0].data.content\u0027 | jq .\n```\n\u003cimg width=\"1916\" height=\"851\" alt=\"poc\" src=\"https://github.com/user-attachments/assets/f3ad34da-f8ac-4e29-9360-3cf1d1f706d8\" /\u003e\n\n\n### Impact\n---\n\n- Since the server performs outbound requests to internal networks, localhost, and metadata endpoints, an attacker can abuse the server\u2019s\u00a0network position to access internal resources (internal APIs, management ports, cloud metadata, etc.).\n\n- As a result, this can lead\u00a0to exposure of internal system information, leakage of authentication tokens/secret keys (e.g., IMDSv1/v2), misuse of internal admin interfaces, and\u00a0provide a foothold for further lateral movement.\n\n- By leveraging user-supplied\u00a0impls\u00a0to force the unfiltered\u00a0naive\u00a0implementation, SSRF defenses\u2014such as blocking private/metadata IPs, DNS re-validation/re-resolution, and\u00a0redirect restrictions\u2014can be bypassed.",
"id": "GHSA-fgx4-p8xf-qhp9",
"modified": "2025-10-17T21:32:47Z",
"published": "2025-10-17T17:46:09Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/lobehub/lobe-chat/security/advisories/GHSA-fgx4-p8xf-qhp9"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62505"
},
{
"type": "WEB",
"url": "https://github.com/lobehub/lobe-chat/commit/8d59583dca16f218b99213d641733d8ba77f182c"
},
{
"type": "PACKAGE",
"url": "https://github.com/lobehub/lobe-chat"
},
{
"type": "WEB",
"url": "https://github.com/lobehub/lobe-chat/blob/d942a635b36a231156c60d824afa573af8032572/packages/web-crawler/src/crawImpl/naive.ts#L39-L45"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:N/A:N",
"type": "CVSS_V3"
}
],
"summary": "Lobe Chat vulnerable to Server-Side Request Forgery with native web fetch module"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.