fix(security): address vulnerabilities from security audit#1242
Conversation
- SSRF: block private IPs and metadata endpoints in webfetch/MCP (DNS rebinding protection) - Auth: enforce password on non-loopback bind, remove auth_token query param - XSS: sanitize markdown HTML (DOMPurify), escape OAuth error templates - Share: require bearer token for share_create, guard getData/fetch on secret existence - Rate limiting: add sliding-window limiter to prompt_async and shell routes - Info disclosure: strip stack traces from error responses and ErrorBoundary - Logging: remove sensitive data from stripe/feishu webhook logs - Webhook: verify Feishu X-Lark-Signature (SHA-256) - Pagination: cap session messages at 1000, default limit 100
URL parsers normalize ::ffff:127.0.0.1 to ::ffff:7f00:1 (hex form), which bypassed the dotted-decimal regex. Now parses both forms.
opencode is a user-facing CLI tool — users legitimately fetch from their own local dev servers. Block private networks and cloud metadata only.
- SSRF: DNS resolution failure now rejects (fail-closed) - Feishu: require signature for all non-challenge requests - Rate limiter: add periodic sweep to prevent memory leak - Tests: add unit tests for SSRF module and rate limiter
Re-review (19a9508)上一轮 4 个 finding 已全部修对 👍 (#3 DNS fail-closed / #7 Feishu 签名 / #6 sweep / #15 tests)。本轮新发现两个不在已有清单里的问题。 🔴 必须看1. SSRF 被 HTTP 重定向绕过 ——
2. 默认 message 接口静默截断到最新 100 条,且无分页游标
🟡 建议3. Feishu 签名缺时间戳新鲜度校验 → 重放 4. 对“不改”清单的意见基本认同。补充:#4 (DNS rebinding) 接受可以,但 结论:🔴#1 (redirect SSRF) 和 🔴#2 (默认接口静默截断) 建议合并前处理,其余为建议项。 Co-authored-by: MiMo-Code noreply@mimo.xiaomi.com |
…arse - webfetch: use safeFetch with redirect:"manual" + per-hop SSRF check to prevent 302-to-internal-IP bypass - session messages: raise default limit from 100 to 1000 (matches max validation) to avoid silent data loss for API consumers - feishu: reject timestamps older than ±5 minutes (replay window) - feishu: wrap JSON.parse in try/catch, return 400 on malformed body - add safeFetch redirect tests to ssrf.test.ts
…esolution The Effect type signature of WebFetchTool is part of the tool registry's Layer requirements. Removing it caused runtime Layer resolution failures in the full test suite.
…SRF check Replacing Effect's HttpClient with native fetch broke the full test suite due to Effect Layer/fiber dependencies across the tool registry. Revert to the original HttpClient.execute() pipeline and add a post-response check: if the response was redirected, validate the final URL against the SSRF blocklist before returning content to the AI.
Bun.serve socket allocation may cause resource contention in the full CI test suite (332 files). Replace with globalThis.fetch mocks that test the same redirect-checking logic without binding ports.
…pollution bun test runs all files in the same process; mocking globalThis.fetch leaked to other test files and broke 19 tool.edit tests in CI.
Summary
修复安全审计发现的 25 个漏洞,覆盖 SSRF、XSS、认证绕过、信息泄露、速率限制等类别。
Changes
P0 — Critical
packages/opencode/src/util/ssrf.tsNEW): 新增 SSRF 检查模块,阻止私有 IP (10.x, 172.16-31.x, 192.168.x)、云元数据端点 (169.254.169.254, metadata.google.internal)、IPv4-mapped IPv6 绕过;集成到 webfetch 和 MCP remote connectserver.ts): 非 loopback 绑定时强制要求 MIMOCODE_SERVER_PASSWORDapi.ts): share_create 需要 Bearer token;getData/fetch 在 secret 不存在时返回空/404P1 — High
content-markdown.tsx): DOMPurify 清洗 markdown HTML 输出middleware.ts): 错误响应移除 stack trace,仅返回 messagemiddleware.ts): 删除 query param 认证方式webhook.ts,api.ts): stripe/feishu webhook 不再记录完整请求体P2 — Medium
oauth-callback.ts,codex.ts): HTML 模板中 error 参数使用 escapeHtmlrate-limit.tsNEW,session.ts): prompt_async 和 shell 路由添加滑动窗口限流 (20 req/min)session.ts): messages 查询添加 .max(1000) 校验和默认 limit: 100[shareID].tsx): 移除 stack trace 显示api.ts): Feishu webhook 验证 X-Lark-Signature (SHA-256)Files Changed (13 files)
Test Plan