fix: configure Echo IPExtractor to prevent rate limit bypass via spoofed headers

This commit is contained in:
kolaente 2026-03-20 10:07:04 +01:00 committed by kolaente
parent 26324a740a
commit a498dd6991
1 changed files with 40 additions and 0 deletions

View File

@ -54,6 +54,7 @@ package routes
import (
"context"
"log/slog"
"net"
"strings"
"time"
@ -125,6 +126,24 @@ func NewEcho() *echo.Echo {
}),
})
// Configure IP extraction to prevent rate limit bypass via spoofed headers.
// Echo's default RealIP() trusts X-Forwarded-For and X-Real-IP unconditionally,
// which allows attackers to bypass IP-based rate limits.
// See: https://echo.labstack.com/docs/ip-address
switch config.ServiceIPExtractionMethod.GetString() {
case "xff":
trustOptions := parseTrustedProxies(config.ServiceTrustedProxies.GetString())
e.IPExtractor = echo.ExtractIPFromXFFHeader(trustOptions...)
log.Debugf("IP extraction: X-Forwarded-For with %d trusted proxy ranges", len(trustOptions))
case "realip":
trustOptions := parseTrustedProxies(config.ServiceTrustedProxies.GetString())
e.IPExtractor = echo.ExtractIPFromRealIPHeader(trustOptions...)
log.Debugf("IP extraction: X-Real-IP with %d trusted proxy ranges", len(trustOptions))
default:
e.IPExtractor = echo.ExtractIPDirect()
log.Debugf("IP extraction: direct (TCP remote address)")
}
e.Logger = log.NewEchoLogger(config.LogEnabled.GetBool(), config.LogHTTP.GetString(), config.LogFormat.GetString())
// Logger
@ -181,6 +200,27 @@ func NewEcho() *echo.Echo {
return e
}
func parseTrustedProxies(proxies string) []echo.TrustOption {
if proxies == "" {
return nil
}
var options []echo.TrustOption
for _, cidr := range strings.Split(proxies, ",") {
cidr = strings.TrimSpace(cidr)
if cidr == "" {
continue
}
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
log.Warningf("Invalid trusted proxy CIDR %q: %v", cidr, err)
continue
}
options = append(options, echo.TrustIPRange(ipNet))
}
return options
}
func setupSentry(e *echo.Echo) {
if !config.SentryEnabled.GetBool() {
return