Second-Order Blind SSRF via Asynchronous Webhook Pipelines
Exploring why synchronous URL validation fails when background task queues fetch webhook targets asynchronously without re-validating DNS resolutions.
Background
Webhooks are ubiquitous in SaaS applications for sending event-driven notifications to customers. To protect internal infrastructure from Server-Side Request Forgery (SSRF), applications commonly validate customer-supplied URLs against private IP ranges (e.g., RFC 1918, 169.254.169.254, 127.0.0.1).
However, a serious vulnerability emerges when validation occurs at registration time, but execution occurs minutes or hours later in worker containers.
The Vulnerability Architecture
1. **Registration**: Submitter provides `https://webhook.attacker.example/receive`.
2. **Synchronous Check**: The API resolves `webhook.attacker.example` to `203.0.113.50` (Public IP). Check passes; URL saved to database.
3. **Execution**: An event occurs. The worker process reads the URL and dispatches an HTTP POST request.
4. **DNS Rebinding**: The attacker's DNS server now responds with TTL=0 and IP `169.254.169.254`.
5. **Exploitation**: The worker connects to the cloud metadata service and forwards AWS IAM session tokens back to the attacker.
Key Takeaways & Defense-in-Depth
**Validate at Connection Time, Not Validation Time**: The HTTP client socket must pin the connection to the validated IP directly.
**Dedicated Egress Proxies**: Route all external webhook requests through an isolated DMZ proxy with hardware egress firewalls blocking private CIDR blocks.
**Disable Redirects**: Prevent the destination server from issuing a 302 redirect back into private internal microservice hostnames.