开源前加固认证与部署契约:加密随机 JWT、改密事务吊销、登录 CSRF,并禁止生产回落 localhost。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -67,6 +67,12 @@ func (s *SettingService) ImportTimelineFromGit(urls []string, followPages bool)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: timelineGitHTTPTimeout,
|
||||
Transport: &http.Transport{
|
||||
// 解析后按公网 IP 拨号,避免 DNS rebinding(与 SMTP/S3 safeDial 同思路)
|
||||
DialContext: publicOnlyDial,
|
||||
TLSHandshakeTimeout: timelineGitHTTPTimeout,
|
||||
ForceAttemptHTTP2: true,
|
||||
},
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= 3 {
|
||||
return errors.New("重定向过多")
|
||||
@@ -656,6 +662,35 @@ func assertSafeHTTPSURL(u *url.URL) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// publicOnlyDial 先解析主机、拒绝私网,再按 IP 拨号,关闭 DNS rebinding 窗口。
|
||||
func publicOnlyDial(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
host, port, err := net.SplitHostPort(address)
|
||||
if err != nil {
|
||||
return nil, errors.New("连接地址无效")
|
||||
}
|
||||
ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
|
||||
if err != nil || len(ips) == 0 {
|
||||
return nil, errors.New("地址解析失败")
|
||||
}
|
||||
var last error
|
||||
dialer := &net.Dialer{Timeout: timelineGitHTTPTimeout}
|
||||
for _, a := range ips {
|
||||
if !isPublicIP(a.IP) {
|
||||
last = errors.New("禁止访问内网地址")
|
||||
continue
|
||||
}
|
||||
c, e := dialer.DialContext(ctx, network, net.JoinHostPort(a.IP.String(), port))
|
||||
if e == nil {
|
||||
return c, nil
|
||||
}
|
||||
last = e
|
||||
}
|
||||
if last == nil {
|
||||
last = errors.New("禁止访问内网地址")
|
||||
}
|
||||
return nil, last
|
||||
}
|
||||
|
||||
func isPublicIP(ip net.IP) bool {
|
||||
if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsMulticast() || ip.IsUnspecified() {
|
||||
return false
|
||||
@@ -664,6 +699,10 @@ func isPublicIP(ip net.IP) bool {
|
||||
if ip4[0] == 169 && ip4[1] == 254 {
|
||||
return false
|
||||
}
|
||||
// CGNAT / 文档网段等
|
||||
if ip4[0] == 100 && ip4[1] >= 64 && ip4[1] <= 127 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user