TL;DR - Key Insights

Figure: High-level SSRF attack surface overview (rendered with Mermaid)

  • SSRF allows attackers to make servers fetch data from internal systems
  • Cloud metadata services (169.254.169.254) are prime targets for credential theft
  • DNS rebinding can bypass naive IP blacklists dynamically
  • IP encoding bypasses simple string-based filters
  • Defense requires: Resolve → Inspect → Block approach
  • Whitelist-based validation is more secure than blacklisting

Understanding SSRF: The Core Vulnerability

Server-Side Request Forgery (SSRF) is a critical web vulnerability that allows attackers to force a server to make unintended HTTP requests to arbitrary destinations. This transforms the compromised server into an unwitting proxy, accessing resources it was never designed to reach.

graph TD
    A[Attacker Input<br/>Malicious URL targeting internal resources] --> B[Vulnerable Application<br/>Server processes request without proper validation]
    B --> C[Internal Target<br/>Access to metadata services, admin panels, or databases]
    C --> D[Data Compromise<br/>Sensitive information exposed to attacker]

Why SSRF Remains Critical

Despite being well-documented, SSRF continues to plague modern applications due to:

  • Incomplete protections
  • Over-reliance on hostname blacklists

The vulnerability's impact is amplified in cloud environments where it can lead to full infrastructure compromise.


Basic SSRF Exploitation

Typical SSRF Scenario

Example of how a URL preview feature can be exploited for SSRF

# Normal request
GET /preview?url=http://example.com HTTP/1.1
Host: vulnerable.com

# Malicious SSRF payload
GET /preview?url=http://127.0.0.1:8000/admin HTTP/1.1
Host: vulnerable.com

# Result: Server fetches internal admin panel

The vulnerability emerges when applications fail to properly validate or sanitize URL parameters, allowing attackers to redirect server requests to internal services.


Common SSRF Targets

Risk LevelTarget TypeExamples
HIGHLocalhost ServicesInternal applications and admin panels
CRITICALCloud MetadataAWS, GCP, Azure instance metadata
MEDIUMInternal NetworksPrivate APIs and dashboards
HIGHBackend ServicesRedis, Elasticsearch, databases
MEDIUMFile SystemsLocal file access via file:// protocol
LOWNetwork ScanningPort scanning and service discovery

Cloud Metadata Exploitation

The Goldmine: 169.254.169.254

This special IP address hosts instance metadata services across major cloud providers.
Successful SSRF exploitation here can lead to complete cloud environment compromise through IAM credential theft and configuration exposure.


AWS Metadata Service v1

No Authentication – Direct access to instance metadata and IAM credentials

Endpoint:
http://169.254.169.254/latest/meta-data/

curl -X GET "http://169.254.169.254/latest/meta-data/"

AWS Metadata Service v2 (IMDSv2)

Token Required – Token-based metadata access with additional security

Endpoint:
http://169.254.169.254/latest/api/token

curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600"

Google Cloud Metadata

Header Required – Access to instance metadata and service account tokens

Endpoint:
http://169.254.169.254/computeMetadata/v1/instance/

curl -X GET "http://169.254.169.254/computeMetadata/v1/instance/" \
-H "Metadata-Flavor: Google"

Azure Instance Metadata

Header Required – Instance configuration and managed identity tokens

Endpoint:
http://169.254.169.254/metadata/instance?api-version=2021-02-01

curl -X GET "http://169.254.169.254/metadata/instance?api-version=2021-02-01" \
-H "Metadata: true"

Advanced Bypass Techniques

RiskTechniqueExample
MEDIUMDecimal Encoding2130706433 -> 127.0.0.1
MEDIUMHexadecimal Encoding0x7f000001 -> 127.0.0.1
MEDIUMOctal Encoding017700000001 -> 127.0.0.1
LOWURL Encoding%31%32%37%2e%30%2e%30%2e%31
CRITICALDNS Rebindingevil.com -> 127.0.0.1 (time-based)

DNS Rebinding: Dynamic Origin Deception

A sophisticated attack that dynamically resolves domain names to internal IP addresses, bypassing simple domain-based filters.

Attack Flow

CRITICAL Bypass Technique:
Attacker controls a domain that initially resolves to a public IP, passes validation, then resolves to 169.254.169.254 during the actual request.


SSRF Attack Map

%%{init: {"theme":"dark","themeVariables":{"fontSize":"14px","fontFamily":"monospace"},"flowchart":{"defaultRenderer":"elk"}}}%%
flowchart TD
 subgraph Legend[" "]
        L1["Attack Path"]
        L2["Bypass Technique"]
        L3["Cloud Target"]
        L4["Defense Layer"]
        L5["Critical Risk"]
  end
    A["Attacker Input<br/>Malicious URL"] --> B{"Vulnerable App<br/>Processes URL?"}
    B -- Yes --> C1["Localhost Services<br/>(127.0.0.1:8000/admin)"] & C2["Internal Networks<br/>(10.0.0.0/8, 192.168.x.x)"] & C3["Backend Services<br/>(Redis, DB, ES)"] & C4["File System<br/>file://etc/passwd"] & C5["Port Scanning"] & D["Target: 169.254.169.254<br/>Cloud Metadata Service"]
    D --> D1["AWS IMDSv1<br/>No Auth"] & D2["AWS IMDSv2<br/>Token Required"] & D3["Google Cloud<br/>Metadata-Flavor: Google"] & D4["Azure IMDS<br/>Metadata: true"]
    D1 --> E[["IAM Roles / Service Account Tokens<br/>Full Cloud Compromise"]]
    D2 --> E
    D3 --> E
    D4 --> E
    B --> F["Bypass Filters?"]
    F -- Decimal --> F1["2130706433 → 127.0.0.1"]
    F -- Hex --> F2["0x7f000001 → 127.0.0.1"]
    F -- Octal --> F3["017700000001 → 127.0.0.1"]
    F -- URL Encode --> F4["%31%32%37%2e%30%2e%30%2e%31"]
    F -- DNS Rebinding --> F5[["evil.com → 1.2.3.4<br/>→ 169.254.169.254"]]
    G["Defense Strategy: Resolve → Inspect → Block"] --> H1["1. DNS Resolution<br/>Resolve Early &amp; Consistently"] & H2["2. IP Inspection<br/>Block RFC 1918 / 3927 IPs"] & H3["3. URL Whitelisting<br/>Allow Only Known Domains"] & H4["4. Egress Firewall<br/>Block 169.254.169.254"]
    H3 --> H3a["Regex + Normalization<br>Parse Host, Path, Port"] & H3b["Log Blocked Requests"] & I{{"Attack Blocked"}}
    H4 --> H4a["Default Deny Outbound<br>Allow Only HTTPS:443"] & H4b["Monitor & Alert on Egress"] & I
    H1 --> I
    H2 --> I
     L1:::attack
     L2:::bypass
     L3:::cloud
     L4:::defense
     L5:::critical
     C1:::attack
     C2:::attack
     C3:::attack
     C4:::attack
     C5:::attack
     D:::cloud
     D1:::cloud
     D2:::cloud
     D3:::cloud
     D4:::cloud
     E:::critical
     F1:::bypass
     F2:::bypass
     F3:::bypass
     F4:::bypass
     F5:::critical
     G:::defense
     G:::defense
     H1:::defense
     H1:::defense
     H2:::defense
     H2:::defense
     H3:::defense
     H3:::defense
     H4:::defense
     H4:::defense
     H3a:::defense
     H3b:::defense
     I:::defense
     H4a:::defense
     H4b:::defense
  classDef attack fill:#ff4d4d,stroke:#a00,color:#fff,fontWeight:bold
    classDef bypass fill:#ff8c1a,stroke:#cc6600,color:#fff
    classDef cloud fill:#3399ff,stroke:#0066cc,color:#fff
    classDef defense fill:#2eb82e,stroke:#006400,color:#fff
    classDef critical fill:#cc0000,stroke:#800,color:#fff
    style Legend fill:none,stroke:none

Comprehensive Defense Strategies

Whitelisting vs Blacklisting

HIGH PRIORITY: Implement strict allowlists of permitted destinations instead of trying to block known bad ones.

Implementation Checklist

  • Define specific allowed domains and IP ranges
  • Implement regex patterns for permitted URLs
  • Regularly review and update whitelist entries
  • Log all blocked requests for monitoring
if (!isWhitelisted(url)) { 
    throw new SecurityException('URL not in allowlist'); 
}

Blacklists are easily bypassed with encoding and DNS tricks.
Whitelists provide stronger security posture.


DNS Resolution Security

HIGH PRIORITY: Validate both hostname and resolved IP addresses before making requests.

Implementation Checklist

  • Resolve DNS before and after URL validation
  • Block private IP ranges (RFC 1918, RFC 3927)
  • Implement consistent DNS resolution timing
  • Use secure DNS resolvers with monitoring
const resolvedIP = await dns.resolve(hostname); 
if (isPrivateIP(resolvedIP)) block();

DNS rebinding attacks exploit timing between validation and execution. Resolve consistently.


Network-Level Controls

HIGH PRIORITY: Implement strict egress filtering

Implementation Checklist

  • Block access to metadata services
  • Restrict outbound connections by default
  • Allow only necessary external services
  • Monitor and log all egress traffic

Outbound Firewall Rules
Network-level controls provide defense in depth


Application-Level Validation

MEDIUM PRIORITY: Input sanitization and normalization

Implementation Checklist

  • Normalize URLs before validation
  • Parse and validate each URL component
  • Implement timeout controls
  • Use dedicated HTTP client libraries

Combine with network controls for comprehensive protection


Secure Your Applications Against SSRF

Follow the golden rule: Resolve → Inspect → Block

  1. Resolve DNS early and consistently
  2. Inspect both URL and resolved IP
  3. Block anything not explicitly allowed

Prevention > Detection — Whitelist everything. Trust nothing.


By PlaidNox Security Team
Originally published June 2025