mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-11-03 00:33:13 +00:00
- B1: 移除根目录 docker-compose.yml(个人镜像测试产物混入) - B2: 新增迁移 224 放宽 user_platform_quotas CHECK 至 8 平台,补 BulkInsertInitial 国产平台集成测试与迁移内容断言测试 - B3: CC/Responses×anthropic 四个上游读循环接入间隔超时泵 (gateway.stream_data_interval_timeout,默认 180s):上游挂住 SSE 不发数据也不断连时结束排水/组装、关闭 resp.Body 归还连接池位, 排水超时仍按已累计 usage 返回(与 messages 主路径同语义) - B4: 配额/余额探测发起前过 cnValidateProbeURL(与网关转发同一套 security.url_allowlist 策略),被拒时零出站、API key 不离开本机
49 lines
1.9 KiB
Go
49 lines
1.9 KiB
Go
package service
|
||
|
||
// CN 供应商探测端点的出站 URL 安全策略校验(配额/余额探测共用)。
|
||
//
|
||
// 背景(review B4):这两条探测路径会把账号 API key 发往 base_url 衍生端点,
|
||
// 此前完全绕过 security.url_allowlist——在加固部署里构成任意外发与内网探测
|
||
// 面(本项目此前发生过账号测试 SSRF 生产事件)。与网关转发
|
||
// (validateUpstreamBaseURL)、Grok 探测(grokOperatorPolicyValidator)一致,
|
||
// 探测发起前必须过同一套运营者策略。
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"strings"
|
||
|
||
"github.com/Wei-Shaw/sub2api/internal/config"
|
||
"github.com/Wei-Shaw/sub2api/internal/util/urlvalidator"
|
||
)
|
||
|
||
// cnValidateProbeURL 按全局出站 URL 安全策略校验探测端点,返回规范化 URL。
|
||
// 白名单开启时强制 UpstreamHosts(阻断私网与未列名主机);关闭时仅做格式
|
||
// 校验(HTTP 允许与否跟随配置);cfg 为 nil 时退化为纯格式校验。
|
||
func cnValidateProbeURL(cfg *config.Config, raw string) (string, error) {
|
||
trimmed := strings.TrimSpace(raw)
|
||
if trimmed == "" {
|
||
return "", errors.New("probe url is required")
|
||
}
|
||
if cfg != nil && cfg.Security.URLAllowlist.Enabled {
|
||
normalized, err := urlvalidator.ValidateHTTPSURL(trimmed, urlvalidator.ValidationOptions{
|
||
AllowedHosts: cfg.Security.URLAllowlist.UpstreamHosts,
|
||
RequireAllowlist: true,
|
||
AllowPrivate: cfg.Security.URLAllowlist.AllowPrivateHosts,
|
||
})
|
||
if err != nil {
|
||
return "", fmt.Errorf("probe target rejected by URL security policy: %w", err)
|
||
}
|
||
return normalized, nil
|
||
}
|
||
var allowInsecureHTTP bool
|
||
if cfg != nil {
|
||
allowInsecureHTTP = cfg.Security.URLAllowlist.AllowInsecureHTTP
|
||
}
|
||
normalized, err := urlvalidator.ValidateURLFormat(trimmed, allowInsecureHTTP)
|
||
if err != nil {
|
||
return "", fmt.Errorf("probe target rejected by URL security policy: %w", err)
|
||
}
|
||
return normalized, nil
|
||
}
|