fix: check X-Real-IP and X-Forwarded-For

This commit is contained in:
Derrick Hammer 2024-03-10 08:40:44 -04:00
parent 71cb44dc61
commit 45a483989c
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
1 changed files with 35 additions and 16 deletions

View File

@ -11,6 +11,7 @@ import (
"net" "net"
"net/url" "net/url"
"nhooyr.io/websocket" "nhooyr.io/websocket"
"strings"
) )
var _ service.Service = (*HTTPServiceDefault)(nil) var _ service.Service = (*HTTPServiceDefault)(nil)
@ -86,25 +87,43 @@ func (h *HTTPServiceDefault) p2pHandler(ctx jape.Context) {
ip := peer.GetIP() ip := peer.GetIP()
switch v := ip.(type) { // Check for reverse proxy headers
case *net.IPNet: realIP := ctx.Request.Header.Get("X-Real-IP")
if v.IP.IsLoopback() { forwardedFor := ctx.Request.Header.Get("X-Forwarded-For")
err := peer.End()
if err != nil { var clientIP net.IP
h.Logger().Error("error ending peer", zap.Error(err)) if realIP != "" {
} clientIP = net.ParseIP(realIP)
return } else if forwardedFor != "" {
// X-Forwarded-For can contain multiple IP addresses separated by commas
// We take the first IP in the list as the client's IP
parts := strings.Split(forwardedFor, ",")
clientIP = net.ParseIP(parts[0])
} }
blockConnection := func(ip net.Addr) bool {
// If we have a valid client IP from headers, use that for the loopback check
if clientIP != nil {
return clientIP.IsLoopback()
}
// Otherwise, fall back to the peer's IP
switch v := ip.(type) {
case *net.IPNet:
return v.IP.IsLoopback()
case *net.TCPAddr: case *net.TCPAddr:
if v.IP.IsLoopback() { return v.IP.IsLoopback()
default:
return false
}
}
if blockConnection(ip) {
err := peer.End() err := peer.End()
if err != nil { if err != nil {
h.Logger().Error("error ending peer", zap.Error(err)) h.Logger().Error("error ending peer", zap.Error(err))
} }
return return
} }
}
h.Services().P2P().ConnectionTracker().Add(1) h.Services().P2P().ConnectionTracker().Add(1)