skills/lu1sdv/skillsmd/ssrf-testing

ssrf-testing

SKILL.md

SSRF Testing & Prevention

Overview

Find, exploit, and fix Server-Side Request Forgery. SSRF tricks the server into making HTTP requests to unintended destinations -- accessing internal services, cloud metadata, or other systems that the server can reach but the attacker cannot.

Normal flow:
  User -> Server -> External API (intended)

SSRF attack:
  User sends: url=http://169.254.169.254/latest/meta-data/
  Server -> AWS Metadata Service (unintended)
  Server returns: IAM credentials, instance info, etc.

Quick Reference

What Details
OWASP A10:2021 Server-Side Request Forgery
CWE CWE-918
Severity Critical (CVSS 9.1) when cloud metadata or internal data exposed
Key tools Burp Suite Pro, SSRFmap, interactsh, Gopherus
Common params url, uri, link, href, src, dest, redirect, callback, webhook, image_url, feed_url, proxy_url
Cloud metadata IP 169.254.169.254 (AWS/Azure/DO), metadata.google.internal (GCP), 100.100.100.200 (Alibaba)
Blind detection Timing differences, OOB callbacks (Collaborator/interactsh), error message variations

When to Use

  • Application fetches user-supplied URLs server-side (webhooks, URL previews, image imports, PDF generators)
  • Testing for access to cloud metadata endpoints
  • Auditing URL validation / allowlist bypass
  • Implementing SSRF prevention controls

When NOT to use:

  • Client-side request forgery (CSRF) -- different vulnerability class
  • CORS misconfigurations without server-side fetch
  • Open redirects that don't chain into server-side requests

Prerequisites

  • Authorization: Written penetration testing agreement including SSRF testing scope
  • Burp Suite Professional: With Collaborator for out-of-band detection
  • interactsh: Open-source OOB interaction server (go install github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest)
  • SSRFmap: Automated SSRF exploitation framework (git clone https://github.com/swisskyrepo/SSRFmap.git)
  • Gopherus: Generates gopher payloads for internal services (git clone https://github.com/tarunkant/Gopherus.git)
  • curl: For manual SSRF payload testing
  • Knowledge of target infrastructure: Cloud provider (AWS, GCP, Azure), internal IP ranges

SSRF Types

Non-blind (Classic) SSRF

The server returns the response body to the attacker:

Request:  GET /fetch?url=http://internal-api:8080/admin/users
Response: {"users": [...all internal user data...]}

Blind SSRF

Server makes the request but doesn't return the response body. Confirm through:

  • Timing differences: Open port = fast, closed port = timeout
  • Out-of-band callbacks: DNS/HTTP request to attacker-controlled server
  • Error message differences: "Connection refused" vs "Host unreachable"

Semi-blind SSRF

Partial information leaks -- error messages, response times, status codes, or content length.

Workflow

Step 1: Identify SSRF-Prone Functionality

Any feature that takes a URL from user input and fetches it server-side is a potential vector:

  • URL preview/unfurling (Slack-style link previews)
  • Webhook configuration endpoints
  • File import from URL (CSV, images, documents)
  • PDF/screenshot generation from URL
  • Image/avatar fetching from URL
  • RSS/feed aggregation
  • OAuth callback URLs
  • API proxy/gateway features
# Test common parameter names for SSRF
for param in url uri link href src dest redirect callback webhook \
  image_url avatar_url feed_url import_url proxy_url path; do
  echo -n "Testing param: $param -> "
  curl -s -o /dev/null -w "%{http_code}" --max-time 3 \
    "https://target.example.com/api/fetch?${param}=http://COLLABORATOR_ID.oast.fun/${param}"
  echo
done

Step 2: Test Internal Access

See references/payloads.md for complete payload lists including:

  • Localhost access variants
  • Internal network scanning scripts
  • Kubernetes internal service names
  • Internal admin panel paths

Step 3: Cloud Metadata Exploitation

See references/payloads.md for cloud metadata endpoints across AWS, GCP, Azure, DigitalOcean, and Alibaba Cloud.

Step 4: Bypass SSRF Filters

When basic payloads are blocked, see references/payloads.md for:

  • IP address encoding (octal, hex, decimal, IPv6, short form)
  • DNS rebinding techniques
  • URL parsing tricks (fragment confusion, username-in-URL, path traversal)
  • Protocol smuggling (file://, gopher://, dict://)

Step 5: Exploit for Impact Escalation

Chain SSRF with internal services for maximum impact:

# Access Elasticsearch
curl -s -X POST -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:9200/_cat/indices?v"}' \
  "https://target.example.com/api/fetch-url"

# Redis via gopher -- use Gopherus to generate payloads
python gopherus.py --exploit redis

Step 6: Blind SSRF Detection

# Time-based: compare response times for open vs closed ports
time curl -s -X POST -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:22/"}' \
  "https://target.example.com/api/fetch-url"

time curl -s -X POST -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:12345/"}' \
  "https://target.example.com/api/fetch-url"

# OOB callback: use Burp Collaborator or interactsh
# If DNS/HTTP callback received, blind SSRF confirmed

Classification

Status Meaning Criteria
VALIDATED SSRF confirmed Internal content returned, cloud metadata exposed, or OOB callback received
FALSE_POSITIVE Not vulnerable All internal requests blocked, no bypass succeeded
PARTIAL Possible SSRF Response differs for internal URLs but no clear content leak; requires manual review
UNVALIDATED Inconclusive Error, timeout, or ambiguous response

Static Analysis (SAST)

See references/sast.md for complete SAST coverage including:

  • Dangerous sink functions by language (PHP, Go, TypeScript/Node.js, Python)
  • Semgrep rules for each language
  • Static analysis tooling (Semgrep, CodeQL, Bandit, gosec, Psalm)
  • Code review checklist

PHP has the most sinksfile_get_contents, curl_exec, SoapClient, GD image functions, XML parsers, and stream wrappers all accept URLs. Check allow_url_fopen and allow_url_include in php.ini.

Prevention

See references/prevention.md for complete prevention code and architecture patterns including:

  • URL validation with DNS resolution (Python)
  • Cloud metadata protection (IMDSv2)
  • Architecture-level defenses (network segmentation, dedicated fetcher, DNS pinning)

Common Mistakes

Mistake Why it fails Fix
Only testing 127.0.0.1 Filters often block literal localhost but miss encodings Test all IP encoding variants (octal, hex, decimal, IPv6)
Skipping blind SSRF No response body ≠ no vulnerability Use timing + OOB callbacks
Ignoring non-HTTP protocols gopher:// and file:// bypass HTTP-only defenses Test protocol smuggling
Testing only IMDSv1 AWS may have IMDSv2 enabled Check both; IMDSv2 requires PUT with token header
Allowlist on hostname only DNS rebinding bypasses hostname checks Validate resolved IP, not just hostname
Missing POST body params SSRF params may be in JSON body, not query string Test both GET params and POST body fields

Common Scenarios

Webhook URL -> AWS Credentials

Webhook callback endpoint accepts user URL. Point to http://169.254.169.254/latest/meta-data/iam/security-credentials/ to retrieve temporary IAM credentials for S3/EC2 access.

PDF Generator -> Internal Admin

PDF generation from URL makes server-side requests. Provide http://127.0.0.1:8080/admin to render internal admin panel into the PDF.

Image URL -> Local File Read

Avatar URL field filtered for HTTP/HTTPS but accepts file://. Use file:///etc/passwd to read local files.

Blind SSRF -> Internal Redis RCE

URL fetch doesn't return response but confirms success/failure. Gopher protocol payloads write data to internal Redis, achieving remote code execution.

Tools Reference

Tool Purpose
Burp Suite Pro Request modification + Collaborator for blind SSRF
SSRFmap Automated SSRF exploitation with protocol support
interactsh Out-of-band interaction detection for blind SSRF
Gopherus Generates gopher payloads for internal services
rbndr.us DNS rebinding service for filter bypass
singularity DNS rebinding attack framework

Output Format

## SSRF Vulnerability Finding

**Vulnerability**: Server-Side Request Forgery (Full/Blind SSRF)
**Severity**: Critical (CVSS 9.1)
**Location**: POST /api/endpoint - `parameter_name`
**CWE**: CWE-918

### Reproduction Steps
1. [Step-by-step with curl commands]

### Confirmed Access
| Target | Protocol | Response |
|--------|----------|----------|
| 169.254.169.254 | HTTP | IAM credentials retrieved |
| 127.0.0.1:6379 | Gopher | Commands executed |

### Impact
- [Concrete impact statements]

### Recommendation
1. Implement strict URL allowlisting
2. Block private IP ranges (10/8, 172.16/12, 192.168/16, 169.254/16)
3. Upgrade to AWS IMDSv2
4. Disable unused URL protocols
5. Use dedicated outbound proxy with DNS resolution controls

Safety Rules

  • ONLY test against authorized targets with written permission
  • NEVER exfiltrate actual cloud credentials (capture evidence, redact values)
  • STOP if destructive action detected (e.g., gopher:// to Redis FLUSHALL)
  • Use benign payloads (INFO, GET) not destructive ones (DELETE, FLUSHALL)
  • Redact all sensitive data in evidence files
  • Report findings through responsible disclosure channels

References

Weekly Installs
1
Repository
lu1sdv/skillsmd
GitHub Stars
1
First Seen
12 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1