The core mechanics: How SSRF weaponizes webhook architecture
A modern payment gateway (like Paystack or Flutterwave) must send asynchronous notifications to its merchants when a transaction succeeds, fails, or is refunded. To achieve this, the gateway provides a dashboard or an API endpoint where the merchant can specify a "Webhook URL". The gateway's backend worker then makes an HTTP POST request to that specific URL containing the transaction payload.
The vulnerability arises when the gateway fails to rigorously validate the URL provided by the merchant before making the outbound HTTP request. An attacker simply signs up for a free merchant account and configures their webhook URL not to an external server they control, but to an internal resource that shouldn't be publicly accessible.
Internal Network Scanning
The attacker sets the URL to internal IP blocks (e.g., `http://10.0.0.5:8080` or `http://192.168.1.1`). Based on the HTTP response times, status codes, or error messages returned to the dashboard, the attacker can systematically map out the internal network topology of the payment gateway, bypassing all external firewalls.
Accessing Internal APIs
The attacker targets internal, unauthenticated administrative APIs (e.g., `http://localhost:9000/admin/flush-cache` or a hidden Redis instance) by forcing the gateway server to make the request to itself (`localhost` or `127.0.0.1`).
Cloud Metadata Extraction (The Kill Shot)
The most devastating and commonly utilized attack involves hitting the cloud provider's metadata service (e.g., `http://169.254.169.254/latest/meta-data/` on AWS) to steal the temporary IAM credentials assigned to the worker node executing the webhook.
A real-world exploit chain: From blind SSRF to cloud compromise
During a recent API security assessment of a rapidly growing Nigerian fintech platform, we identified a highly critical "Blind SSRF" vulnerability within their webhook testing feature. The dashboard allowed merchants to click a "Test Webhook" button, which dispatched a sample payload to the configured URL to ensure connectivity.
The application did not display the raw HTTP response body back to the user interface (hence, "Blind"). However, it did display whether the request was "Successful" or "Failed," and we could measure the exact time it took for the request to complete.
We configured the webhook URL to point to the AWS metadata IP address (`169.254.169.254`). While the application attempted to filter out the literal string "169.254.169.254", we bypassed this filter by encoding the IP address in decimal format (`http://2852039166`).
Because we could not see the response directly, we used a combination of timing attacks and a technique called DNS Rebinding to trick the server into evaluating an external domain as safe, but resolving it to the metadata IP at the exact moment the HTTP request fired. We eventually managed to exfiltrate the IAM role credentials attached to the Kubernetes worker node. This IAM role was grossly over-privileged, granting us full read access to the underlying S3 buckets containing millions of raw KYC documents. A seemingly minor "test" feature completely compromised the entire cloud infrastructure.
Are your webhook dispatchers inadvertently exposing your internal AWS/Azure network?
Book an API Penetration TestDefending against SSRF: A defense-in-depth architecture
Preventing SSRF requires a rigorous, defense-in-depth approach. You cannot rely on simple regular expressions or string matching at the application layer, as attackers have dozens of ways to obfuscate URLs (IPv6, decimal IPs, octal IPs, DNS rebinding).
1. Strict URL validation and resolution (Application Layer)
The application code must parse the provided URL, explicitly resolve the hostname to its underlying IP address, and verify that the resolved IP address does not fall within any reserved private ranges (e.g., `10.0.0.0/8`, `127.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.169.254`).
Crucially, to prevent DNS rebinding attacks, the application must resolve the IP address, validate it, and then make the HTTP request directly to that specific IP address, rather than asking the HTTP client to resolve the hostname again. The Host header should be manually injected back into the request so the remote server processes it correctly.
2. Network isolation for outbound requests (Infrastructure Layer)
The specific microservice or background worker responsible for dispatching webhooks should run in a heavily isolated environment. It should absolutely not be running on the same server that hosts your core database, ledger logic, or internal caching layers.
Configure strict network policies (using Kubernetes NetworkPolicies or AWS Security Groups) so that this specific worker service is only allowed to make outbound connections to the public internet (0.0.0.0/0). It must be explicitly blocked from initiating connections to any internal subnets or the cloud metadata service.
3. Upgrade to IMDSv2 (Cloud Layer)
If you are hosting your infrastructure on AWS, you must immediately enforce the use of Instance Metadata Service Version 2 (IMDSv2) across all EC2 instances and EKS worker nodes. IMDSv2 introduces a session-oriented request method. It requires a client to make a `PUT` request with a specific HTTP header to retrieve a session token before it can query any metadata.
This effectively neutralizes the vast majority of SSRF attacks aiming to steal cloud credentials, because an attacker exploiting an SSRF vulnerability typically only controls the URL being requested, but cannot force the vulnerable application to inject arbitrary HTTP headers (like the `X-aws-ec2-metadata-token` required by IMDSv2).
Do not reinvent HTTP clients
When fetching URLs provided by external users or merchants, do not write raw socket code or use basic, unconfigured HTTP libraries (like Python's raw `urllib` or Node's native `http` module). Use established HTTP clients configured specifically to prevent SSRF. Ensure the client is explicitly configured to not follow HTTP redirects automatically. An attacker can provide a perfectly valid external URL that passes all your filters, but when your server fetches it, the attacker's server responds with an HTTP 302 Redirect pointing back to `http://169.254.169.254`, bypassing your initial validation entirely.
Frequently asked questions
What is Server-Side Request Forgery (SSRF)?
SSRF is a critical vulnerability where an attacker manipulates a vulnerable application into making unauthorized HTTP requests to an arbitrary domain or IP address of the attacker's choosing. The server acts as a proxy, allowing the attacker to bypass external firewalls and access internal, heavily guarded systems.
Why are payment gateways uniquely vulnerable to SSRF attacks?
Payment gateways inherently need to make outbound network requests to client systems to deliver webhooks (e.g., notifying a merchant that a payment succeeded). If the gateway allows the merchant to freely define the webhook URL without strict cryptographic and network validation, attackers can weaponize that outbound request feature.
How does SSRF lead to a total cloud infrastructure breach?
If the vulnerable application is hosted on AWS, an attacker can use SSRF to query the EC2 Instance Metadata Service (IMDS) located at the unroutable IP address 169.254.169.254. By querying this internal API, the attacker can extract the temporary IAM credentials assigned to that specific EC2 server, gaining deep access into the AWS environment.
What is a DNS Rebinding attack in the context of SSRF?
DNS Rebinding is a technique used to bypass simple SSRF filters. The attacker registers a domain name. When the application first checks the domain, the attacker's DNS server returns a safe, external IP. The application validates it. But fractions of a second later, when the application actually makes the HTTP request, the DNS server returns an internal IP (like 127.0.0.1), tricking the server into attacking itself.
Related reading
Blog: Webhook Security for Payment Platforms · Cloud Security Checklist · BOLA in Payment APIs
Guides: Fintech Security Checklist · OWASP Guide for Fintech
Services: API Security Testing · Secure Architecture Review