fix: stabilize console scrolling and protect administrator login
This commit is contained in:
57
internal/transport/httpserver/console_login.go
Normal file
57
internal/transport/httpserver/console_login.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/consoleauth"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// loginRemoteAddress 默认只信任 TCP 对端;仅受信反代可提供 X-Forwarded-For。
|
||||
// 从右往左剥离可信跳点,遇到首个非可信地址即停止;不接受任意客户端伪造的首项。
|
||||
func loginRemoteAddress(r *http.Request, store consoleauth.Store) string {
|
||||
peer, err := netip.ParseAddr(remoteAddress(r))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
peer = peer.Unmap()
|
||||
policyStore, ok := store.(interface {
|
||||
LoginPolicy() consoleauth.LoginPolicy
|
||||
})
|
||||
if !ok {
|
||||
return peer.String()
|
||||
}
|
||||
trusted := policyStore.LoginPolicy().TrustedProxies
|
||||
isTrusted := func(ip netip.Addr) bool {
|
||||
for _, n := range trusted {
|
||||
if n.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
if !isTrusted(peer) {
|
||||
return peer.String()
|
||||
}
|
||||
raw := strings.Join(r.Header.Values("X-Forwarded-For"), ",")
|
||||
if raw == "" || len(raw) > 2048 {
|
||||
return peer.String()
|
||||
}
|
||||
hops := strings.Split(raw, ",")
|
||||
if len(hops) > 32 {
|
||||
return peer.String()
|
||||
}
|
||||
addresses := make([]netip.Addr, len(hops))
|
||||
for i, h := range hops {
|
||||
a, e := netip.ParseAddr(strings.TrimSpace(h))
|
||||
if e != nil {
|
||||
return peer.String()
|
||||
}
|
||||
addresses[i] = a.Unmap()
|
||||
}
|
||||
current := peer
|
||||
for i := len(addresses) - 1; i >= 0 && isTrusted(current); i-- {
|
||||
current = addresses[i]
|
||||
}
|
||||
return current.String()
|
||||
}
|
||||
Reference in New Issue
Block a user