fix(audit): strip IPv6 brackets before INET insert #9

Merged
sharang merged 1 commits from fix/audit-ipv6 into main 2026-05-19 15:09:01 +00:00
+13 -11
View File
@@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"log/slog"
"net"
"net/http"
"strings"
"time"
@@ -87,22 +88,23 @@ func (s *statusRecorder) WriteHeader(c int) {
func clientIP(r *http.Request) string {
if fwd := r.Header.Get("X-Forwarded-For"); fwd != "" {
if i := strings.IndexByte(fwd, ','); i > 0 {
return strings.TrimSpace(fwd[:i])
return stripBrackets(strings.TrimSpace(fwd[:i]))
}
return strings.TrimSpace(fwd)
return stripBrackets(strings.TrimSpace(fwd))
}
if host, _, ok := splitHostPort(r.RemoteAddr); ok {
if host, _, err := net.SplitHostPort(r.RemoteAddr); err == nil {
// net.SplitHostPort returns IPv6 without brackets already.
return host
}
return r.RemoteAddr
return stripBrackets(r.RemoteAddr)
}
// splitHostPort is a port-tolerant version of net.SplitHostPort that doesn't
// error on missing port.
func splitHostPort(s string) (string, string, bool) {
i := strings.LastIndexByte(s, ':')
if i < 0 {
return s, "", false
// stripBrackets removes the `[...]` wrapping IPv6 hosts pick up from
// net/http's RemoteAddr in some Go versions, since Postgres `inet` rejects
// `[::1]` but accepts `::1`.
func stripBrackets(s string) string {
if len(s) >= 2 && s[0] == '[' && s[len(s)-1] == ']' {
return s[1 : len(s)-1]
}
return s[:i], s[i+1:], true
return s
}