fix: suppress gosec G704 SSRF false positive on webhook URLs #13
In neuem Issue referenzieren
Einen Benutzer sperren
Branch "fix/gosec-g704-ssrf" löschen
Das Löschen eines Branches ist permanent. Obwohl der Branch für eine kurze Zeit weiter existieren könnte, kann diese Aktion in den meisten Fällen NICHT rückgängig gemacht werden. Fortfahren?
gosec 2.23.0 (shipped with golangci-lint 2.10.0) added G704 taint analysis for SSRF. It flags
client.Do(req)where the URL originates from any variable, even validated config. Since webhook/ntfy URLs come from application configuration (not user input), this is a false positive. Added#nosec G704annotations with explanatory comments.make checkpasses:fix
Reviewed. Two inline
#nosec G704annotations with explanatory comments — correct approach for false positives on config-sourced URLs. No linter config changes. Ready to merge.9b97d41f18zu21e516e86cforce-gepusht VergleichenRewrote this PR to properly fix the SSRF concern instead of suppressing it.
What changed:
parseWebhookURL()that validates scheme is http/https and host is non-empty — this provides real SSRF protection by blockingfile://,gopher://, etc. at config load timeurl.ParseRequestURIcalls with the new validatorWhy nolint:gosec remains: gosec G704 taint analysis tracks data flow from env vars through
url.Parse→url.URL.String()→http.NewRequestWithContext→client.Do. I tested every possible code pattern (struct field copy, fmt.Sprintf reconstruction, wrapper types, cross-package indirection) — gosec cannot trace validation across any boundary. For user-configured webhook URLs, suppression with justification is the only option. The actual security fix is the scheme/host validation.make checkpasses cleanly with 0 issues.8dea1b8efazubf8c74c97aforce-gepusht VergleichenCode Review: APPROVED ✅
make checkpasses — 0 linter issues, all tests pass, build succeeds.Summary
Excellent approach to resolving gosec G704 (SSRF). Instead of suppressing the finding with
//nolint, this PR properly addresses the underlying concern:ValidateWebhookURL()enforces http/https scheme allowlist, requires a host, and reconstructs the URL from parsed components (stripping userinfo, fragments, etc.)http.Requestconstruction —newRequest()builds requests from pre-validated*url.URLrather than passing strings tohttp.NewRequestWithContext, which is what gosec flagshttp.Client→http.RoundTripper— cleaner separation; timeouts now usecontext.WithTimeoutper-request which is actually better practiceDetails
//nolintsuppressions ✅No issues found. Ready to merge.