Detection Engineering

SSRF Detection Without Exploit Code

SSRF detection without running exploits — metadata-access signatures, Sigma/Suricata/CloudTrail rules, IMDSv2 defense, a CVE-2025-53767 case, and tuning tips.

A network switch with one cyan ethernet cable isolated from the bundle and a red warning LED

SSRF detection does not require you to launch a single exploit. The attack leaves two clean fingerprints: outbound requests from your app to internal IPs it should never reach (especially the cloud metadata endpoint 169.254.169.254), and, in the cloud, instance-role credentials suddenly used from an external IP. Catch either and you catch server-side request forgery — without ever running a payload against your own systems.

SSRF sits at A10:2021 in the OWASP Top 10, and it is still escalating. In 2025, researchers disclosed CVE-2025-53767, an Azure OpenAI SSRF reported at CVSS 10.0 that allowed retrieval of managed-identity tokens. SSRF is how a web bug becomes a cloud-account compromise.

What is SSRF, in a defender’s terms?

Server-side request forgery turns your trusted server into the attacker’s proxy: it makes the internal requests an outsider cannot. From outside, an attacker cannot reach your internal network or your cloud metadata service. With SSRF, your own application makes those requests for them. The prize is usually credentials.

The canonical case is still the 2019 Capital One breach: an SSRF flaw reached the EC2 Instance Metadata Service and walked away with IAM role credentials. It maps to T1190 — Exploit Public-Facing Application for entry and T1552.005 — Unsecured Credentials: Cloud Instance Metadata API for the payoff.

What are the types of SSRF?

Three variants matter for detection, and each names a different destination — which is why the signal is so clean.

VariantWhat the attacker reachesTelemetry fingerprintBest detection layer
Metadata theft169.254.169.254 / metadata.google.internalApp host → link-local metadata IPNetwork + cloud control plane
Internal scanningRFC 1918 ranges, 127.0.0.1App host → internal hosts/ports it never usesNetwork egress
Blind SSRFAttacker-controlled out-of-band hostOutbound DNS/HTTP to a freshly seen domainDNS + egress logs

The common thread: SSRF detection lives in egress, not ingress. That makes it detectable without exploit code — you watch your own outbound traffic.

How to detect SSRF across web and cloud telemetry

Layer it from the triggering request to the credential abuse that follows.

Web tier: requests that name internal targets

The loudest, cheapest signal is a user-supplied URL parameter containing an internal or metadata address — the same web-log approach behind SQL injection detection.

Sigma Web Request Referencing Cloud Metadata or Internal IP
title: Web Request Referencing Cloud Metadata or Internal IP
id: 4f2b9c81-darkpwn-illustrative
status: experimental
logsource:
  category: webserver
detection:
  selection:
    cs-uri-query|contains:
      - '169.254.169.254'
      - 'metadata.google.internal'
      - '169.254.170.2'
      - '127.0.0.1'
      - '://10.'
      - '://192.168.'
  condition: selection
falsepositives:
  - Webhook/health-check features that accept internal URLs by design
level: high

Network tier: egress to the metadata address

Attackers bypass string filters with encodings (octal, decimal-dotted, hex). The reliable catch is on the wire: any connection from your app subnet to 169.254.169.254 that is not the instance agent itself. Reserve SID 1000003+.

Suricata Outbound Request to Cloud Metadata Service
alert http $HOME_NET any -> 169.254.169.254 any (
    msg:"DARKPWN Outbound request to cloud metadata service (possible SSRF)";
    flow:established,to_server;
    classtype:web-application-attack; sid:1000003; rev:1;)

Cloud control plane: credentials used from the wrong place

The highest-fidelity SSRF signal often appears after the request: the instance role’s credentials used from an IP that is not the instance. AWS GuardDuty raises UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration for exactly this; in CloudTrail it is an instance-profile session calling APIs from an external sourceIPAddress.

SPL Instance-Role Credentials Used From Outside the VPC
index=cloudtrail
| where match('userIdentity.arn', "assumed-role/.*i-")
| where NOT cidrmatch("10.0.0.0/8", sourceIPAddress)
    AND NOT cidrmatch("172.16.0.0/12", sourceIPAddress)
| stats count, values(eventName) by 'userIdentity.arn', sourceIPAddress

How to test your SSRF detection safely

Validate the egress rules without attacking anyone:

  1. In a throwaway lab account, stand up an app with a URL-fetch feature you control.
  2. Point it at 169.254.169.254 from the app host and confirm the network rule fires.
  3. Point it at an internal RFC 1918 host and confirm the scanning signal triggers.
  4. Confirm IMDSv2 blocks the credential read even when the fetch succeeds — that’s the control validating itself.

How to defend against SSRF

Detection buys time. These controls remove the worst outcomes.

  • Allowlist outbound URLs, never denylist — denylists fall to encoding and redirect tricks (see the OWASP SSRF Prevention Cheat Sheet).
  • Resolve, validate, then pin the IP before connecting, to defeat DNS rebinding.
  • Least-privilege IAM roles cap the blast radius of a stolen token (NIST 800-53 AC-6).
  • Segment egress — app subnets rarely need arbitrary outbound; default-deny turns blind SSRF into a blocked, logged event.

Common SSRF detection mistakes

  • IMDSv1 left enabled “temporarily.” One legacy workload flipping HttpTokens to optional reopens the Capital One path for the whole fleet.
  • Following redirects without re-validating. An allowlisted URL returns a 302 to 169.254.169.254; if your client follows it blindly, the allowlist is moot.
  • AWS-only coverage. GCP’s metadata.google.internal, Azure IMDS, and the ECS endpoint 169.254.170.2 are reachable by the same bug class.
  • Ingress-only monitoring. SSRF barely shows up at ingress; the signal is in egress and the cloud control plane.

SSRF detection and defense checklist

Work this list top to bottom:

  1. Enforce IMDSv2 (HttpTokens=required), disable IMDSv1, and audit for stragglers.
  2. Allowlist outbound URLs and schemes; never rely on a denylist.
  3. Resolve, validate, then pin the IP before connecting — defeats DNS rebinding.
  4. Re-validate every redirect hop, or disable redirect-following on server-side fetchers.
  5. Default-deny egress on application subnets; allowlist required destinations.
  6. Alert on app hosts reaching 169.254.169.254, RFC 1918 ranges, or new external domains.
  7. Alert on instance-role credentials used from outside the VPC (GuardDuty / CloudTrail).
  8. Scope IAM roles to least privilege to cap the blast radius of a stolen token.
  9. Cover GCP (metadata.google.internal), Azure IMDS, and the ECS endpoint 169.254.170.2.

The takeaway

SSRF is an egress problem with a credential payoff. Instrument what your servers connect to, enforce IMDSv2 so a stolen request cannot read a usable secret, and watch the cloud control plane for the credential that walked out the door. Continue the web-application defense arc with broken access control testing and JWT misconfiguration detection, or browse the full Detection Engineering pillar.

Training & tools referenced

Disclosure: Some links below are affiliate links. If you buy through them, darkpwn may earn a commission at no extra cost to you. We only recommend training and tools we actually use in our own lab, and affiliate links never influence editorial coverage.

  • TryHackMeAuthorized labs to practice SSRF detection and cloud-metadata defenseSecurity Training
    Start training

Frequently asked questions

How do you detect SSRF without running exploits?

Watch your egress, not your ingress. Alert on outbound requests from app hosts to the metadata endpoint 169.254.169.254, to RFC 1918 internal ranges, or to freshly seen external domains from a URL field. In the cloud, alert when instance credentials get used from an IP outside your network.

Does IMDSv2 fully prevent SSRF?

No. IMDSv2 prevents the credential-theft outcome on AWS by requiring a session token and a custom header most SSRF primitives cannot send. The SSRF flaw still exists and can scan internal services, so pair IMDSv2 with allowlist URL validation and egress segmentation.

What is the AWS metadata IP address?

The EC2 Instance Metadata Service lives at the link-local address 169.254.169.254. The ECS task-role endpoint is 169.254.170.2, and GCP uses metadata.google.internal. None of these should appear in a legitimate user-supplied URL.

Which OWASP category is SSRF?

Server-side request forgery is its own category, A10:2021 in the OWASP Top 10, added after it ranked first in the community survey.

Newsletter

Liked this breakdown?

Defensive security research — detection, hardening, and hardware — delivered when there is something worth saying. No spam, unsubscribe anytime.