tracking: 外呼与输入校验面(4 项)—— 外部可控输入未被当作不可信数据
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 12/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Cần làm rõ
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- networking, security
Hướng nghiên cứu
This is a tracking issue with no code of its own; the four child issues (#169 to #172) are the real work, and they must land in order. Start by reading src/tools/policy_domain/url_guard.rs around validate_url and is_private_ip, then src/tools/http_call.rs (encode_segment, build_url), src/tools/a2a.rs (the base interpolation and task_id check), and src/tools/install_skill.rs (slug and extract_zip). Done means the four cluster acceptance checks in the body pass, each with negative tests for the bypass cases.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
优先级 P1 · 依赖:无 · 类型:tracking(簇设计入口,不产出代码;子单全部落地后关闭)
记号:正文中的「不变量 #N」指.dev/AGENTS.md编号,不是 issue 编号;#150这类才是 issue。本簇子单头部写depends-on: #N表示落地串行(同文件/同契约),不会与语义阻塞混淆。
基线 HEAD = 14bac15a(子单同基线)。本单来自一次全仓审计:先按根因归簇,再拆成可独立验收的子单。
共同根因
四条都是「外部可控输入没有被当成不可信数据」,集中在 url_guard 与两个外呼工具:
- SSRF 只查字面主机(#169):
src/tools/policy_domain/url_guard.rs:58-145对Host::Domain仅拦localhost/*.localhost/metadata.google.internal与 IP 字面写法,全仓无自定义 DNS resolver(连接期不校验),且is_private_ip漏100.64/10、0/8(除0.0.0.0)、::a.b.c.d、64:ff9b::/96。169.254.169.254.nip.io这类名字直接放行(重定向绕过已由Policy::none关闭,剩下的就是 DNS 面)。 - 路径逃逸(#170):
src/tools/http_call.rs:437-447的encode_segment保留.,整段..经build_url(:577-586)交给Url::set_path后被解析消解,且不校验最终 path 是否仍以运维 base path 为前缀 → 请求打到网关根路径并带着运维鉴权头。 - shell 注入(#171):
validate_url返回原始输入(url_guard.rs:121),a2a_call把base直接插进单引号命令(src/tools/a2a.rs:272-292),只对task_id做了白名单(:389-409)→ 提前闭合引号的curl|sh可被注入。 - 技能安装缺完整性(#172):
install_dir放行 slug"."(src/tools/install_skill.rs:150-156)→dest变成共享根;extract_zip剥第一层后可在dest内覆盖兄弟技能(:228-258);默认跟随重定向、read_to_end无上限(:290-338、:350-363);slug 未编码即拼 URL(:454-497)。
子单与依赖
| 子单 | 依赖 | 范围 |
|---|---|---|
| #169 | 无 | 自定义 reqwest Resolve:解析结果过 is_private_ip 再连;补齐私网/保留段 |
| #170 | depends-on: #169 | 拒绝 ./.. 参数;断言最终 path 以 base path 为前缀 |
| #171 | depends-on: #170 | 用规范化 Url;拒绝 ' " \ $ \ 空白`;优先 argv/env 传参 |
| #172 | depends-on: #171 | slug 白名单 [A-Za-z0-9_-]+;redirect(none) + sha256 pin;entry/总量双上限 |
落地思路
- #169 不需要新依赖(不变量 #6 不受影响):本机 reqwest 0.12.28 已提供
ClientBuilder::dns_resolver与reqwest::dns::Resolve;把校验放在 resolver 里比放在validate_url里更难绕过(连接期生效)。 - 顺序按同文件串行:#169 与 #171 都动
url_guard.rs,#170/#171 都动src/tools/与 URL 拼装,#172 依赖同一套出站校验约定。 - #170 加的是不变量式断言(
final_url.path().starts_with(base_path)),比逐个过滤字符更可靠。 - 与 B 簇在
url_guard.rs(validate_url被权限面复用)相邻;与 G 簇在src/tools/相邻,按全局顺序错开。
簇级验收
WebFetch/a2a对nip.io形态、DNS rebinding 形态与100.64.x.x全部被拒;http_call的id=".."构建失败;正常id="42"路径为/{base}/42;a2a_call收到含'/空白/;的 URL 时返回错误而非生成可执行命令;install_skill拒 slug".";含..//绝对路径/超限的 zip 被拒且无文件落盘。
边界
不含鉴权与租户身份(G 簇 #152、#146);不含 SKILL 内容来源的信任模型(#64/#76/#77 已定的 SkillSource 边界)。
实施顺序、PR 拆分与验收矩阵(补充 · 2026-10-10)
顺序(四单同域,串行):#169 → #170 → #171 → #172。
理由:#169 与 #171 都动 url_guard.rs;#170 与 #171 都动 URL 拼装;#172 依赖同一套"出站 URL 必须经校验"的约定。四单都不大,串行成本可接受。
跨簇重叠:url_guard.rs(validate_url)被权限面复用(B 簇 #153 只改工具名,不改 URL 逻辑,实际不冲突);src/tools/ 目录级重叠与 G 簇相邻。
PR 拆分:一子单一 PR。每个 PR 附"绕过尝试"的负向测试(本簇的价值就在于此)。
簇级验收 → 测试映射:见正文四条,落在 src/tools/policy_domain/url_guard.rs、src/tools/http_call.rs、src/tools/a2a.rs、src/tools/install_skill.rs 的单测中;#169 建议加一个 reqwest resolver 的单测(可用 Resolve trait 的纯函数部分)。
- Ngôn ngữ chính
- Rust
- Star
- 4
- Fork
- 0
- Merge trung bình
- 5 giờ 32 phút
- Pull request đã merge (30 ngày)
- 7
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của jeffkit/recursive
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
jeffkit/recursive#159 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 15/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 15/100
Maintainer thường phản hồi trong vòng 1 ngày
-
tracking: 安全面闭环——已落地机制的绕过(4 项)Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 8/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 12/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của jeffkit/recursive
Issue tương tự
-
C-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
rust-lang/rust-analyzer#23501 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: Web chat input doesn't regain focus after a reply finishesCó thể đã có người làm @GaijinSystems đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
zeroclaw-labs/zeroclaw#11658 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
good first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
bytecodealliance/wasm-tools#2768 ·
Maintainer thường phản hồi trong vòng 1 ngày