Validate and sandbox merchant webhook URLs to prevent SSRF from webhook delivery - #538
Open
EmmanuelAdah wants to merge 11 commits into
Open
Validate and sandbox merchant webhook URLs to prevent SSRF from webhook delivery#538EmmanuelAdah wants to merge 11 commits into
EmmanuelAdah wants to merge 11 commits into
Conversation
…sts and refactor tests to remove direct Axios usage.
…@IsSafeWebhookUrl` and introduce corresponding unit tests.
…feguards, including comprehensive unit tests.
…otection and unit tests
Author
|
Review this PR for any update needed |
Contributor
|
Kindly fix CI |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes SSRF and internal port-scanning vulnerabilities in merchant webhooks by implementing defense-in-depth URL validation, request-time DNS pinning to prevent rebinding, safe bounded redirects, and API error sanitization.
Type of Change
Description
Write-time Validation: Added @IsSafeWebhookUrl() decorator and SsrfProtectionService.assertSafeForWrite() to enforce HTTPS, forbid embedded credentials, and block private/reserved IP ranges on save.
Request-time Enforcement: Replaced raw axios calls with SafeWebhookHttpService. Outbound calls re-resolve hostnames against an IP blocklist (ipaddr.js) and pin the socket to the validated IP to defeat DNS rebinding.
Bounded Redirects: Disabled auto-redirects (maxRedirects: 0). Redirect locations are individually extracted and re-validated per hop up to WEBHOOK_MAX_REDIRECTS (default: 3).
Error Sanitization: Collapsed API-facing delivery errors into generic categories (invalid_destination, unreachable, etc.) to prevent internal network fingerprinting.
Dev Escape Hatch: Added ALLOW_LOCAL_WEBHOOKS=true config (default: false) to allow local/CI testing against loopback addresses.
Testing Evidence
Ran full automated test suite locally:
Bash
pnpm test
Result: 41 test suites passed, 480 tests passed
Automated Coverage: Added unit/integration tests for IP blocklists (loopback, RFC1918, cloud metadata 169.254.169.254, IPv6), write/request-time DNS resolution, DNS-rebinding attack simulations, redirect-to-private-IP blocks, and error-sanitization paths.
Manual Verification: Verified that saving webhook URLs pointing to 127.0.0.1, 10.0.0.5, 169.254.169.254, or http:// endpoints triggers a 400 Bad Request. Verified ALLOW_LOCAL_WEBHOOKS=true permits http://localhost only when explicitly enabled.
Screenshots
N/A (Backend-only change)
Checklist