Slide 12 of 28
Part 2 · How It WorksSlide 12
Slide 12 · Pattern 2 Mechanics
Third-party redirect → Consuming API follows it server-side → Internal target reached
How an SSRF attack is delivered through a trusted third-party redirect instead of direct user input.
THE SETUP
An API that fetches a URL returned by a third-party service to process a file or resource.

The consuming API calls a third-party document processing service. The service returns a JSON response: {"status":"ready","download_url":"https://cdn.processor.example.com/file.pdf"}.

The API fetches the download_url from the response, trusting that a URL returned by a legitimate third-party service is safe to follow. No URL validation is applied — the URL came from a trusted source, not a user.

1️⃣
Attacker compromises or impersonates the third-party
The attacker either compromises the third-party API to return a malicious download_url, or performs a DNS hijack/BGP hijack that causes the consuming API’s DNS resolution of the third-party domain to return an attacker-controlled server. Either way, the consuming API makes a legitimate request to what it believes is the trusted third-party, and receives a response that includes a malicious redirect URL.
2️⃣
Malicious redirect points to internal target
The attacker-controlled response returns: {"download_url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/role"}. The API follows this URL without validation — it came from the trusted third-party — and makes a server-side HTTP request to the AWS metadata endpoint.
3️⃣
Consuming API reaches internal target and returns or stores the response
The metadata endpoint returns IAM credentials. Depending on how the API processes the fetched content, the credentials may be: returned to the attacker in an error message, stored in a database field, or logged — all accessible to the attacker. The API’s SSRF protections (applied to user-supplied URLs) never fired — because the URL came from a trusted third-party response, not a user.
← Back Real incident: Log4Shell via API data →