Skip to content

fix(review): 处理 PR #4 review 发现(SSRF 自动加载/ref 上限/PWA cookie/编辑 path 参/共享 schema)#5

Merged
Yuerchu merged 5 commits into
mainfrom
fix/code-review-fixes
Jun 15, 2026
Merged

fix(review): 处理 PR #4 review 发现(SSRF 自动加载/ref 上限/PWA cookie/编辑 path 参/共享 schema)#5
Yuerchu merged 5 commits into
mainfrom
fix/code-review-fixes

Conversation

@Yuerchu

@Yuerchu Yuerchu commented Jun 15, 2026

Copy link
Copy Markdown
Owner

PR #4 合并后的 review 跟进,处理 5 条 finding(1×P1 + 3×P2 + 1×P3)。

  • P1 use-settings.ts:分享链接(query 串)的 openapi_url 自动加载会无交互 fetch,现拒绝指向内网/loopback 主机的自动加载(SSRF);用户手动输入/legacy URL 不受影响。
  • P2 parser.ts:外部 $ref 读取也走 readResponseTextCapped,同源 ref 不能再返回超大响应吃满内存。
  • P2 vite.config.ts:PWA 不再缓存 same-origin spec(可能 cookie/session 认证,Cookie 头 JS 不可见无法过滤),只缓存跨域 public spec。
  • P2 ConsoleFormDialog/DetailCardTemplate:编辑弹窗接收页面加载用的 path 参数作为 id fallback,响应体不回显 id 时 PUT /users/{id} 不再丢 path 参数。
  • P3 generate-example.ts:pruneCircularRefs 改用祖先路径栈(进入 add/离开 delete),不再把 sibling 字段共享的非循环 schema 误当循环剪成空。

验证

pnpm lint 0 errors(28 个均为预存 warning)· pnpm test 214 passed(含 shared-schema 回归用例)· pnpm typecheck 通过。

🤖 Generated with Claude Code

Yuerchu and others added 5 commits June 15, 2026 14:28
- use-settings: refuse auto-loading a query-string openapi_url pointing at an internal/loopback host (SSRF via share link); user-typed/legacy URLs exempt
- parser: cap external $ref response bodies via readResponseTextCapped too
- vite PWA: don't cache same-origin specs (may be cookie/session authenticated) — only cross-origin public specs
- ConsoleFormDialog/DetailCard: pass loaded path params as id fallback when the response body doesn't echo the id
- generate-example: pruneCircularRefs tracks the ancestor path (not a global set) so shared sibling schemas aren't emptied as false cycles
- tests: shared-schema reuse

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The single-transaction optimization read environments via getAllFromIndex
directly, dropping getEnvironments()'s createdAt sort. The result feeds
use-environments, which picks element [0] as the default environment when none
is saved — and IndexedDB index order ≠ creation order, so the default baseUrl/
auth could silently switch environments. Reuse getEnvironments() (keeps the
sort) and still batch-read credentials in one transaction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… frame-ancestors

- url-guard: replace hand-rolled IP range checks with ipaddr.js (2500M weekly
  downloads, handles IPv4-mapped IPv6 hex form like ::ffff:7f00:1 that the
  manual regex missed — SSRF bypass). ipaddr.process() + .range() covers all
  loopback/private/linkLocal/uniqueLocal/carrierGradeNat/reserved ranges.
- db: redact credential fields BEFORE truncating the body. truncateBody turns
  valid JSON into broken text that redactBody can't parse, leaving secrets in
  the first 2MB unmasked.
- vite/cli: remove frame-ancestors from meta CSP (browsers ignore it there per
  spec); add X-Frame-Options: DENY as the meta-compatible clickjacking defense;
  document that deployers should set frame-ancestors via HTTP response header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- url-guard: add "multicast" to NON_PUBLIC_RANGES (224.0.0.0/4, ff00::/8)
- vite/cli: remove <meta X-Frame-Options> — it's equally unenforceable via meta
  as frame-ancestors; clarify in comments that deployers must set the HTTP header

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…stall)

The earlier commit added ipaddr.js to the main checkout's package.json (where
pnpm add ran) but not this worktree's, so CI's `pnpm install --frozen-lockfile`
installed without it and tsc failed with "Cannot find module 'ipaddr.js'".
Add the dependency to package.json and regenerate the lockfile entry (incremental,
+9 lines, no version drift). Verified frozen-lockfile is consistent under pnpm 10.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Yuerchu Yuerchu merged commit 4fcabab into main Jun 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant