diff --git a/.github/codeql-custom-model.yml b/.github/codeql-custom-model.yml index 5f07eb7a..818ec167 100644 --- a/.github/codeql-custom-model.yml +++ b/.github/codeql-custom-model.yml @@ -39,3 +39,6 @@ extensions: data: # network.IsPrivateIP is a validation function (neutral - doesn't propagate taint) - ["github.com/Wikid82/charon/backend/internal/network", "IsPrivateIP", "manual"] + # TestURLConnectivity validates URLs internally via security.ValidateExternalURL + # and ssrfSafeDialer - it's a terminating function, not a pass-through + - ["github.com/Wikid82/charon/backend/internal/utils", "TestURLConnectivity", "manual"] diff --git a/backend/internal/utils/url_testing.go b/backend/internal/utils/url_testing.go index 6953e4da..e064216f 100644 --- a/backend/internal/utils/url_testing.go +++ b/backend/internal/utils/url_testing.go @@ -276,8 +276,12 @@ func TestURLConnectivity(rawURL string, transport ...http.RoundTripper) (reachab // - Test: url.Parse().String() reconstructs URL (mock transport, no network) // See: internal/security/url_validator.go, internal/network/safeclient.go // - // codeql[go/ssrf] - SSRF protected: validated by security.ValidateExternalURL (DNS resolution + - // private IP blocking) and ssrfSafeDialer (connection-time IP re-validation prevents DNS rebinding) + // codeql[go/request-forgery] Safe: URL validated by security.ValidateExternalURL() which: + // 1. Validates URL format and scheme (HTTPS required in production) + // 2. Resolves DNS and blocks private/reserved IPs (RFC 1918, loopback, link-local) + // 3. Uses ssrfSafeDialer for connection-time IP revalidation (TOCTOU protection) + // 4. Redirect targets validated by validateRedirectTarget() + // lgtm[go/request-forgery] resp, err := client.Do(req) //nolint:bodyclose // Body closed via defer below latency = time.Since(start).Seconds() * 1000 // Convert to milliseconds