From f14574322c8d86ec6c39ae849497a3d4bc8ed8df Mon Sep 17 00:00:00 2001 From: senke Date: Sun, 22 Feb 2026 17:31:10 +0100 Subject: [PATCH] fix(security): add SSRF protection for webhook URL registration SEC-07: Strengthened ValidateWebhookURL to require HTTPS only (was allowing HTTP). Private IP ranges, localhost, and cloud metadata endpoints remain blocked. --- veza-backend-api/internal/validators/url_validator.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/veza-backend-api/internal/validators/url_validator.go b/veza-backend-api/internal/validators/url_validator.go index 19f65768d..c106a0602 100644 --- a/veza-backend-api/internal/validators/url_validator.go +++ b/veza-backend-api/internal/validators/url_validator.go @@ -78,16 +78,16 @@ func isPrivateIP(ip net.IP) bool { return false } -// ValidateWebhookURL validates that a webhook URL does not target internal or private resources (SSRF protection). -// Returns an error if the URL is unsafe. +// ValidateWebhookURL validates that a webhook URL is safe for registration. +// SEC-07: Only HTTPS allowed. Blocks private/internal IPs (SSRF protection). func ValidateWebhookURL(rawURL string) error { parsed, err := url.Parse(rawURL) if err != nil { return fmt.Errorf("invalid URL: %w", err) } scheme := strings.ToLower(parsed.Scheme) - if scheme != "http" && scheme != "https" { - return fmt.Errorf("unsupported URL scheme %q: only http and https are allowed", parsed.Scheme) + if scheme != "https" { + return fmt.Errorf("only https URLs are allowed for webhooks (got %q)", parsed.Scheme) } hostname := strings.ToLower(parsed.Hostname()) if hostname == "" {