EresusSecurity
Back to Research
Security Advisories

ERESUS-ADV-2026-002: Server-Side Request Forgery (SSRF) via Cloud Metadata Endpoints

Yiğit İbrahim SağlamOffensive Security Specialist
March 28, 2026
4 min read

Summary

During routine offensive security assessments and cloud penetration testing engagements, Eresus Labs identified a recurring, high-impact Server-Side Request Forgery (SSRF) vulnerability pattern affecting modern cloud-native applications hosted on AWS, Google Cloud Platform (GCP), and Microsoft Azure. Designated as ERESUS-ADV-2026-002, this vulnerability class enables unauthenticated remote attackers to coerce server-side backend components into querying link-local cloud metadata endpoints, extracting temporary IAM security credentials, service account tokens, and infrastructure configurations.

Affected Cloud Architectures & Target Endpoints

Applications accepting user-supplied URLs (e.g., webhook configurations, document converters, PDF generators, and proxy caching mechanisms) without strict egress filtering are susceptible. When running on virtual instances with default configurations, attackers target the following link-local metadata endpoints:

1. Amazon Web Services (AWS EC2 / ECS)

  • Endpoint: http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>
  • Payload Target: Temporary access keys (AccessKeyId, SecretAccessKey, Token) assigned to the instance profile.

2. Google Cloud Platform (GCP Compute Engine)

  • Endpoint: http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
  • Header Requirement Bypass: While GCP requires Metadata-Flavor: Google, legacy endpoints (/0.1/ or /v1beta1/) or applications forwarding client headers allow token extraction.

3. Microsoft Azure (Azure VMs / App Services)

  • Endpoint: http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/
  • Payload Target: JSON Web Tokens granting Azure Resource Manager (ARM) management access.

Exploitation Anatomy & Attack Walkthrough

sequenceDiagram
    autonumber
    actor Attacker
    participant App as Web Application (Vulnerable)
    participant IMDS as Cloud Metadata Service (169.254.169.254)
    participant CloudAPI as Cloud Provider API (AWS/GCP/Azure)

    Attacker->>App: POST /api/generate-pdf?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
    App->>IMDS: HTTP GET /latest/meta-data/iam/security-credentials/
    IMDS-->>App: Returns Assigned IAM Role Name ("AppProductionRole")
    App->>IMDS: HTTP GET /latest/meta-data/iam/security-credentials/AppProductionRole
    IMDS-->>App: Returns STS Session Credentials (AccessKey, SecretKey, Token)
    App-->>Attacker: Returns Extracted Cloud Credentials in Response
    Attacker->>CloudAPI: Authenticate with stolen STS Token & Exfiltrate S3/DB
  1. Reconnaissance: The attacker identifies an input parameter that triggers server-side HTTP requests (e.g., url, callback, webhook, target).
  2. Metadata Query: The attacker supplies http://169.254.169.254/latest/meta-data/iam/security-credentials/.
  3. Credential Harvester: The server queries IMDS and returns the IAM Role name. A second request fetches the full temporary credential block.
  4. Cloud Pivot: The attacker configures their local AWS CLI with the stolen keys and enumerates permissions via aws sts get-caller-identity.

CVSS 3.1 Base Score & Vector

  • CVSS Score: 8.6 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
    • Scope (S): Changed — The vulnerability in the web application leads to unauthorized access in an entirely separate authority (the cloud provider IAM subsystem).

Code-Level Remediation: Safe HTTP Client Implementation

Blocking SSRF requires defensive network validation before the HTTP request is dispatched. Below is a hardened Python helper verifying that target IPs do not resolve to private or link-local ranges:

import ipaddress
import socket
import urllib.parse
import requests

def safe_fetch(url: str, timeout: int = 5):
    parsed = urllib.parse.urlparse(url)
    if parsed.scheme not in ('http', 'https'):
        raise ValueError("Invalid protocol scheme")

    # Resolve IP address to prevent DNS Rebinding
    hostname = parsed.hostname
    ip_addr = socket.gethostbyname(hostname)
    ip_obj = ipaddress.ip_address(ip_addr)

    # Disallow private, loopback, link-local, and reserved ranges
    if (ip_obj.is_private or ip_obj.is_loopback or 
        ip_obj.is_link_local or ip_obj.is_reserved):
        raise SecurityError(f"Access to internal IP {ip_addr} is blocked")

    return requests.get(url, timeout=timeout, allow_redirects=False)

Infrastructure Hardening Checklist

  1. Mandate AWS IMDSv2: Enforce session-oriented metadata access across all EC2 instances and launch templates:
    aws ec2 modify-instance-metadata-options \
      --instance-id i-0123456789abcdef0 \
      --http-tokens required \
      --http-endpoint enabled
    
  2. Set Hop Limit to 1 in Containerized Environments: When running Docker or Kubernetes on EC2, set --http-put-response-hop-limit 1 so container pods cannot reach the node's host-level IMDS.
  3. Implement Least Privilege IAM Roles: Restrict instance profile permissions strictly to necessary operational resources. Never attach AdministratorAccess or broad S3/DynamoDB wildcard policies.
  4. Egress Firewall Enforcement: Configure iptables or cloud security groups to block all outbound instance traffic destined for 169.254.169.254/32 for web workers that have no legitimate metadata requirements.

Disclosure & Credit

This advisory was formulated by the Eresus Labs offensive research team following recurring vulnerability discoveries during enterprise cloud penetration tests. Detailed remediation guidance has been coordinated with affected organizations.

Security Validation

Have you tested this risk in your own system?

Eresus Security delivers real exploit evidence through penetration testing, AI agent security, and red team operations.

Request a pilot test

Related Services