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.
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.
| Variant | What the attacker reaches | Telemetry fingerprint | Best detection layer |
|---|---|---|---|
| Metadata theft | 169.254.169.254 / metadata.google.internal | App host → link-local metadata IP | Network + cloud control plane |
| Internal scanning | RFC 1918 ranges, 127.0.0.1 | App host → internal hosts/ports it never uses | Network egress |
| Blind SSRF | Attacker-controlled out-of-band host | Outbound DNS/HTTP to a freshly seen domain | DNS + 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.
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+.
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.
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:
- In a throwaway lab account, stand up an app with a URL-fetch feature you control.
- Point it at
169.254.169.254from the app host and confirm the network rule fires. - Point it at an internal RFC 1918 host and confirm the scanning signal triggers.
- 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
HttpTokenstooptionalreopens 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 endpoint169.254.170.2are 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:
- Enforce IMDSv2 (
HttpTokens=required), disable IMDSv1, and audit for stragglers. - Allowlist outbound URLs and schemes; never rely on a denylist.
- Resolve, validate, then pin the IP before connecting — defeats DNS rebinding.
- Re-validate every redirect hop, or disable redirect-following on server-side fetchers.
- Default-deny egress on application subnets; allowlist required destinations.
- Alert on app hosts reaching
169.254.169.254, RFC 1918 ranges, or new external domains. - Alert on instance-role credentials used from outside the VPC (GuardDuty / CloudTrail).
- Scope IAM roles to least privilege to cap the blast radius of a stolen token.
- Cover GCP (
metadata.google.internal), Azure IMDS, and the ECS endpoint169.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 TrainingStart 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.