fix(security): SSRF guard + ripgrep timeout (proposal)#5
Open
Closed-Book wants to merge 1 commit into
Open
Conversation
新增 fetch SSRF 防御(M1)+ ripgrep timeout(M3)。属 nice-to-have 安全纵深,请作者判断是否合并: fetcher/http.ts: - 改 redirect: 'manual' 手动跟随,max=5 跳 - 每跳前 dns.lookup() 检查目标 IP 是否在 RFC 1918 / RFC 6890 私网范围(127/8 / 10/8 / 172.16/12 / 192.168/16 / 169.254/16 / ::1 / fc00::/7),拒则抛 PrivateAddressError - env opt-out LOREKIT_FETCH_ALLOW_PRIVATE=1 跳过私网检查 - 不影响 ollama localhost(在 lib/ollama.ts 另一路径) fetcher/index.ts: - L1 catch 时识别 PrivateAddressError,直接冒泡为 FetchResult error (reason=PRIVATE_ADDRESS_BLOCKED),不退 L2 fallback (否则 playwright 也会绕过 guard 命中私网) search.ts: - spawnSync 加 timeout: 30_000(之前仅 maxBuffer 10M) - SIGTERM 触发时落 fallback + warn 新增 tests/smoke/fetch-ssrf.test.mjs 验证私网拒绝 + opt-out。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
本 PR 引入行为变更:fetch 默认拒绝私网 URL(RFC 1918 / 6890 范围)。在 lorekit 用户场景(个人知识库抓公网文章)下不影响常规用法,但如果你有意让 fetch 抓自建 localhost wiki,需要明确决策:
Option A:合并,按 default deny + env opt-out 走(本 PR 的设计)
Option B:拒绝合并,文档化让用户自己注意
Option C:合并但 default allow + 加 `--block-private` flag opt-in
本 PR 实现的是 Option A(更安全的默认),但所有 default-deny 都有 env 逃生口 `LOREKIT_FETCH_ALLOW_PRIVATE=1`。
Summary
SSRF 防御细节
ripgrep timeout
纯加 `timeout: 30_000`,规避恶意 query / 退化 regex 在巨型 corpus 上 hang 风险。SIGTERM 时落到内置 fallback + warn。零业务副作用。
Verification
```bash
npm run verify # 全绿(53 旧测试 + 2 新 ssrf 测试 = 55 pass / 1 skip / 0 fail)
```
实测输出:
```
ℹ tests 55
ℹ pass 54
ℹ fail 0
ℹ skipped 1
```
`tsc --noEmit` 也是 clean;`npm run lint` 在 http.ts / fetcher/index.ts / 新 smoke 上零问题(search.ts 的 unused-import warn 是预先存在的,与本 PR 无关)。
Context
来自一次对 lorekit v0.4.0 的代码审查 + GPT-5.4 对抗 review。M3 ripgrep timeout 是纯收益、建议直接接受;M1 SSRF 是 nice-to-have、看作者偏好。
🤖 Generated with Claude Code