From ec789274b1f5093f956d71d05b1cf88327e925d5 Mon Sep 17 00:00:00 2001 From: guoyangzhen Date: Sun, 15 Mar 2026 21:41:55 +0800 Subject: [PATCH] fix: handle IPv6 brackets and port in X-Forwarded-For parsing The validateHeader function failed to parse X-Forwarded-For values with: - IPv6 addresses in brackets: [240e:318:2f4a:de56::240] - Port numbers: 192.168.8.39:38792 - Both: [240e:318:2f4a:de56::240]:38792 Use net.SplitHostPort to properly handle all formats, falling back to bracket stripping for bare bracketed IPv6 addresses. Fixes #4572 --- gin.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gin.go b/gin.go index 2e033bf3..5504c5ba 100644 --- a/gin.go +++ b/gin.go @@ -486,6 +486,17 @@ func (engine *Engine) validateHeader(header string) (clientIP string, valid bool items := strings.Split(header, ",") for i := len(items) - 1; i >= 0; i-- { ipStr := strings.TrimSpace(items[i]) + + // Handle IPv6 with brackets and/or port: [::1], [::1]:8080, 192.168.1.1:8080 + // net.SplitHostPort handles all these cases and strips brackets + if host, _, err := net.SplitHostPort(ipStr); err == nil { + ipStr = host + } else { + // No port present, just strip brackets if any (bare IPv6 like [::1]) + ipStr = strings.TrimPrefix(ipStr, "[") + ipStr = strings.TrimSuffix(ipStr, "]") + } + ip := net.ParseIP(ipStr) if ip == nil { break