Category: security
Problem
src/webhooks/dto/create-webhook.dto.ts validates url with only @IsString() (line 7) — not @IsUrl(), no protocol restriction, and no check against internal/private IP ranges. WebhooksService.create() (src/webhooks/webhooks.service.ts line 34) persists whatever string is given and WebhookDeliveryService later has a Bull worker POST to it.
Impact
A malicious or compromised merchant account can register a webhook URL pointing at an internal service (e.g. http://169.254.169.254/latest/meta-data, http://localhost:6379, or another internal host), and the backend's own outbound HTTP call (presumably made from the webhook-delivery Bull processor) becomes an SSRF vector against internal infrastructure.
Suggested fix
Add @IsUrl({ protocols: ['https'], require_protocol: true }) to the DTO and, at delivery time, resolve the hostname and reject private/loopback/link-local IP ranges before making the outbound request.
Category: security
Problem
src/webhooks/dto/create-webhook.dto.ts validates
urlwith only@IsString()(line 7) — not@IsUrl(), no protocol restriction, and no check against internal/private IP ranges.WebhooksService.create()(src/webhooks/webhooks.service.ts line 34) persists whatever string is given andWebhookDeliveryServicelater has a Bull worker POST to it.Impact
A malicious or compromised merchant account can register a webhook URL pointing at an internal service (e.g.
http://169.254.169.254/latest/meta-data,http://localhost:6379, or another internal host), and the backend's own outbound HTTP call (presumably made from the webhook-delivery Bull processor) becomes an SSRF vector against internal infrastructure.Suggested fix
Add
@IsUrl({ protocols: ['https'], require_protocol: true })to the DTO and, at delivery time, resolve the hostname and reject private/loopback/link-local IP ranges before making the outbound request.