X2 C1-3(自排工具面与提示词): - request_think(thinktool.go,照 transcode/tool.go 范式)+ reason 必填/urgency 闭集 + 双守门 (安全闸 + owner 判定:群聊/陌生人一律拒) - **成对**进两张唤醒态允许集(quiet + awake;CAPACITY_TOOL_SETS 是整体替换) - 提示词抽共用段落 + 自排前缀优先(不枚举工具清单);面板加 self_wake 标签与筛选轴 - 4 个变异自检(拿掉 owner 判定/只加一张表/放宽 urgency/前端标签恒等) X3 收口(与 X2 共用 wire_services.go ⇒ 一并落): - 删掉第三份 SSRF 实现(guard.go),改由 io.ValidateRequestURL 唯一判定 + 薄门面(保两个错误身份) - 浏览器会话挂进 a.close(真机:真 Chrome 被关、无残留、生产未扰动) - a.wireBrowser() 归位到 wire_runtime.go,删掉 ioToolOptions 的临时挂点 - 5 个变异自检 顺带补提交 C1-2 漏掉的 internal/config/runtimeconfig/backthink_test.go(ed50053 漏 add)。
42 lines
2.2 KiB
Go
42 lines
2.2 KiB
Go
package browser
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"net/url"
|
||
|
||
iotools "git.yeij.top/AskaEth/Cyrene_v2/plugins/tools/io"
|
||
)
|
||
|
||
// GuardURL 是浏览器侧访问 SSRF 判定的**唯一入口**,判定本体**只有一份**:
|
||
// `plugins/tools/io.ValidateRequestURL`(design/28 §4:「复用既有 `io/ssrf` 白名单,
|
||
// **不新增第三份实现**」)。
|
||
//
|
||
// **为什么这里只留一层薄门面(切片 X3 的收口)**:本包原先自带一份与 io 同策的实现
|
||
// (`guard.go`:自己的 scheme 判定 + 网段表 + 白名单比对),只因为当时 io 侧的
|
||
// `validateRequestURL` 没导出、该包又不在那一片的文件面里。两份同策代码的危险不在
|
||
// 当下的结论,而在**以后只改一处** —— 改完两边静默分叉,浏览器侧的导航就成了绕过面。
|
||
// 收口后本文件只做两件事:
|
||
//
|
||
// 1. 调 `io.ValidateRequestURL`(**唯一**判定源:scheme → 白名单短路 → 字面 IP 网段
|
||
// 否决 → 解析后再按同一张表否决);
|
||
// 2. 把它的错误翻成本包对外的 `ErrBlockedURL` —— 这是**契约**不是判定:
|
||
// `ErrBlockedURL` / `ReasonBlockedURL` 是工具层与组合根(含后续 M3 面板入口)用来
|
||
// 分类降级与记日志的标识,收口只搬判定,不动契约。
|
||
//
|
||
// 两个错误身份都保住(`%w:%w`):`errors.Is(err, ErrBlockedURL)` 成立(本包契约),
|
||
// 网段/解析类拒绝上 `errors.Is(err, iotools.ErrSSRF)` 同样成立(判定源),io 侧的原因
|
||
// 文案(哪个网段、解析到哪个地址)一字不丢地进日志。形状错误(空 URL、非 http(s))
|
||
// 在 io 侧本就不带 ErrSSRF,那几档只有本包身份。
|
||
//
|
||
// 为什么浏览器侧必须有这道闸:导航是**服务端代取用户/模型给的任意 URL**,不过闸就
|
||
// 等于把云元数据端点(`169.254.169.254`)、内网管理面暴露给一次提示词注入
|
||
// (design/28 §4 第 1 条;M3 面板入口同样过闸)。
|
||
func GuardURL(ctx context.Context, rawURL string, allowed []string) (*url.URL, error) {
|
||
u, err := iotools.ValidateRequestURL(ctx, rawURL, allowed)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("%w:%w", ErrBlockedURL, err)
|
||
}
|
||
return u, nil
|
||
}
|