itsjustshubh/Phia

GitHub: itsjustshubh/Phia

揭示生产环境中5个未认证API端点的安全风险与修复方案。

Stars: 0 | Forks: 0

# Phia API — 研究 **作者:** Shubh Thorat  ·  **日期:** 2026年4月11日  ·  **目标:** `api.phia.com` ## 我发现了什么 **5 个端点在生产环境中无需身份验证即可接受请求。** 最关键的一个是 `CreateMerchantUrl`:它会为**任意**用户的账户生成关联追踪链接,且不需要令牌。我传入一个伪造的 UUID,却得到了一个实时的关联 URL: ``` curl -X POST https://api.phia.com/v2/graphql \ -H "Content-Type: application/json" \ -H "x-platform: EXTENSION" \ -d '{ "operationName": "CreateMerchantUrl", "variables": { "input": { "phiaId": "00000000-0000-0000-0000-000000000000", "url": "https://poshmark.com/listing/any-item", "platform": "EXTENSION", "searchId": "test", "productId": "ENTITY_TYPE_PRODUCT-abc123", "secondhandRetailerId": "POSHMARK" }}, "query": "mutation CreateMerchantUrl($input: CreateMerchantUrlInput!) { createMerchantUrl(input: $input) { id url } }" }' ``` **响应 —— `200 OK`,未进行身份验证检查:** ``` { "data": { "createMerchantUrl": { "id": "1516e925-3864-43a1-ab2a-102a8ff0ebef", "url": "https://www.anrdoezrs.net/click-101090659-15736479?url=..." } } } ``` 任何人都可以涌入关联点击,污染任意用户的分析数据,并无限调用 CJ 和 Impact.com —— 而这一切都不需要会话。 ## 所有发现 | # | 端点 | 严重程度 | 问题描述 | | --- | ------------------------- | -------- | ---------------------------------------------------------------------------------------------- | | 1 | `CreateMerchantUrl` | **严重** | 无身份验证,无 `phiaId` 归属检查 —— 大规模的关联欺诈 | | 2 | `CreateResaleInsightsUrl` | 高 | 无身份验证 —— `link` 参数原样反射到输出 URL | | 3 | `GET /whitelist/validate` | 高 | `phiaId` 以 URL 查询参数形式暴露 —— 泄露到服务器日志、浏览器历史记录和 Referer 头部 | | 4 | 分析令牌 | 中 | Mixpanel 令牌硬编码在公共的 `background.js` 中 —— 任何人都可注入伪造事件 | | 5 | GraphQL 自省 | 低 | `__schema` 返回 `500`,而非干净的禁用错误 | ## 负载测试 编写了一个 [Locust](https://locust.io) 脚本(`load_test.py`),并发地对全部 5 个未认证端点发起请求,针对生产环境进行测试。 Locust load test results | 端点 | 请求数 | 失败数 | 中位延迟 | p95 延迟 | p99 延迟 | 最大延迟 | 平均大小 | | ------------------------- | :----: | :----: | -----------: | ------------: | ---------------: | ---------------: | --------: | | `CreateMerchantUrl` | 19 | **0** | 210ms | 660ms | 660ms | 657ms | 314 B | | `CreateResaleInsightsUrl` | 25 | **0** | 44ms | 58ms | 130ms | 127ms | 361 B | | `GET /whitelist/validate` | 4 | **0** | 150ms | 180ms | 180ms | 177ms | 206 B | | `GenerateEntityId` | 7 | **0** | 44ms | 49ms | 49ms | 49ms | 69 B | | `SiteConfig` | 10 | **0** | 570ms | 1100ms | 1100ms | 1148ms | 63 B | | **汇总** | **65** | **0** | **130ms** | **590ms** | **1100ms** | **1148ms** | **260 B** | **65 次请求,0 次失败。每次调用都返回真实数据,无需身份验证。** 平均大小这一列证实了这些并非空错误。`CreateMerchantUrl` 每次调用返回 **314 字节的实时关联数据**。`SiteConfig` 在少量流量下达到 **1148 毫秒** —— 每次调用都会链式调用两个 gRPC 向下游。在真实负载下,这将成为第一个瓶颈。 完整报告:[`Report/Locust.html`](Report/Locust.html) ## 如何修复 **1. 在 `CreateMerchantUrl` 上要求身份验证 + 归属检查** ``` @Authorized() async createMerchantUrl(input, context) { if (input.phiaId !== context.user.phiaId) throw new ForbiddenError('phiaId mismatch'); } ``` **2. 将 `phiaId` 移出 URL 参数** — 使用 GraphQL 请求中已存在的 `x-phia-id` 头部。永远不要将永久用户标识符放在查询字符串中。 **3. 轮换并代理分析令牌** — `0707dbc4f9ae6bc96db7b740d1c4911a` 存在于公共扩展包中。轮换它,并在服务器端代理事件,使令牌永不触达客户端。 **4. 禁用生产环境中的自省功能** ``` new ApolloServer({ introspection: process.env.NODE_ENV !== "production" }); ``` **5. 对未认证端点实施速率限制** — 每 IP 至少每分钟 30 次请求。 ## 方法论 未使用专有工具 —— 仅依靠 DevTools、Python、curl 和 Locust。 ``` Chrome DevTools → HAR export (597 entries captured) Python → parsed every request, isolated unauthenticated endpoints curl → manually confirmed each finding against production Locust → load_test.py — concurrent load across all 5 endpoints ``` --- 欢迎在 staging 环境逐步验证或进行更深入的测试。
标签:0失败请求, 65请求, API安全, API测试, CreateMerchantUrl, CURL, GraphQL, HAR分析, JSON输出, Locust压力测试, MITM代理, 分析污染, 后端开发, 无认证端点, 未授权访问, 漏洞披露, 生产环境, 用户账户劫持, 端点枚举, 补丁建议, 负载测试, 逆向工具, 链接反射, 附属欺诈