From 01922291f600d302fe61ed3654fb28061f2bb1f3 Mon Sep 17 00:00:00 2001 From: Niklas Ye Date: Fri, 9 Oct 2026 15:27:45 +0200 Subject: [PATCH] Satisfy gosec on the proxy count and the request log G115: the trusted-proxy count is stored as an int64 instead of narrowing it to int32. G706: the request logger and serverError quote the request method and route; the logger's remaining taint comes from the wrapped response writer, so it carries a justified nosec like the other quoted log lines. Claude-Session: https://claude.ai/code/session_016mBLURvJoMuUEr9cB2RpUN --- internal/api/auth.go | 2 +- internal/api/helpers.go | 2 +- internal/api/middleware.go | 2 +- internal/api/router.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/api/auth.go b/internal/api/auth.go index 100acfb..38feff9 100644 --- a/internal/api/auth.go +++ b/internal/api/auth.go @@ -132,7 +132,7 @@ func purgeRateLimits(ctx context.Context, db *sql.DB) { // trustedProxies is how many X-Forwarded-For hops clientAddr trusts. Set once // by NewRouter from config. -var trustedProxies atomic.Int32 +var trustedProxies atomic.Int64 // clientAddr is the address a login is counted against. Behind the gateway // RemoteAddr is the gateway itself, so the client address is read from diff --git a/internal/api/helpers.go b/internal/api/helpers.go index 1b73b51..2ae751e 100644 --- a/internal/api/helpers.go +++ b/internal/api/helpers.go @@ -77,7 +77,7 @@ func serverError(w http.ResponseWriter, r *http.Request, err error) { if rc := chi.RouteContext(r.Context()); rc != nil && rc.RoutePattern() != "" { route = rc.RoutePattern() } - log.Printf("%s %s: %v", r.Method, route, err) + log.Printf("%s %s: %v", strconv.Quote(r.Method), strconv.Quote(route), err) respond(w, http.StatusInternalServerError, errResp("internal error")) } diff --git a/internal/api/middleware.go b/internal/api/middleware.go index a9e0fc6..462b386 100644 --- a/internal/api/middleware.go +++ b/internal/api/middleware.go @@ -447,6 +447,6 @@ func requestLogger(next http.Handler) http.Handler { if status == 0 { status = http.StatusOK } - log.Printf("%s %s %d %dB %s", r.Method, route, status, ww.BytesWritten(), time.Since(start).Round(time.Millisecond)) + log.Printf("%q %q %d %dB %s", r.Method, route, status, ww.BytesWritten(), time.Since(start).Round(time.Millisecond)) // #nosec G706 -- method and route are %q-quoted, the route is a registered pattern, the rest are numbers }) } diff --git a/internal/api/router.go b/internal/api/router.go index 14ff537..aceecd1 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -23,7 +23,7 @@ func NewRouter(db *sql.DB, notify NotifyConfig, cfg config.Config, version strin // One limiter each, both process-wide for the life of the router: login // counts failed passwords, sign-up counts account creation, and mixing the // two would let a burst of sign-ups lock somebody out of logging in. - trustedProxies.Store(int32(cfg.TrustedProxies)) + trustedProxies.Store(int64(cfg.TrustedProxies)) loginLimit := newLoginLimiter(db) signupLimiter := newLoginLimiter(db) oidcLimit := newLoginLimiter(db)