@@ -902,9 +902,18 @@ func trustedRealClientIP(r *http.Request, headers []string, clientIP string) str
902
902
allValues := strings .Split (strings .Join (values , "," ), "," )
903
903
904
904
// Get first valid left-most IP address
905
- for _ , ip := range allValues {
906
- ip , _ , _ = strings .Cut (strings .TrimSpace (ip ), "%" )
907
- ipAddr , err := netip .ParseAddr (ip )
905
+ for _ , part := range allValues {
906
+ // Some proxies may retain the port number, so split if possible
907
+ host , _ , err := net .SplitHostPort (part )
908
+ if err != nil {
909
+ host = part
910
+ }
911
+
912
+ // Remove any zone identifier from the IP address
913
+ host , _ , _ = strings .Cut (strings .TrimSpace (host ), "%" )
914
+
915
+ // Parse the IP address
916
+ ipAddr , err := netip .ParseAddr (host )
908
917
if err != nil {
909
918
continue
910
919
}
@@ -921,11 +930,20 @@ func trustedRealClientIP(r *http.Request, headers []string, clientIP string) str
921
930
// remote address is returned.
922
931
func strictUntrustedClientIp (r * http.Request , headers []string , trusted []netip.Prefix , clientIP string ) string {
923
932
for _ , headerName := range headers {
924
- ips := strings .Split (strings .Join (r .Header .Values (headerName ), "," ), "," )
933
+ parts := strings .Split (strings .Join (r .Header .Values (headerName ), "," ), "," )
934
+
935
+ for i := len (parts ) - 1 ; i >= 0 ; i -- {
936
+ // Some proxies may retain the port number, so split if possible
937
+ host , _ , err := net .SplitHostPort (parts [i ])
938
+ if err != nil {
939
+ host = parts [i ]
940
+ }
941
+
942
+ // Remove any zone identifier from the IP address
943
+ host , _ , _ = strings .Cut (strings .TrimSpace (host ), "%" )
925
944
926
- for i := len (ips ) - 1 ; i >= 0 ; i -- {
927
- ip , _ , _ := strings .Cut (strings .TrimSpace (ips [i ]), "%" )
928
- ipAddr , err := netip .ParseAddr (ip )
945
+ // Parse the IP address
946
+ ipAddr , err := netip .ParseAddr (host )
929
947
if err != nil {
930
948
continue
931
949
}
0 commit comments