Join our Newsletter — 33% off our NHI Course
Home› Guides› SSRF Prevention Guide: Cloud Metadata Services and URL…
Guide Application Security

SSRF Prevention Guide: Cloud Metadata Services and URL Validation

← All guides
By Lalit Choda, NHI Mgmt Group Updated 18 October 2026 17 min read
On this page

Server-side request forgery (SSRF) turns an application's own network position and credentials into the attacker's: any feature that fetches a URL on a user's behalf can be steered to internal services, cloud control planes or the instance metadata service that hands out workload credentials. URL previews, webhooks, image and file imports, document renderers and AI agent tools all make outbound requests, and each one is a potential SSRF entry point. This guide covers how full read and blind SSRF work, cloud metadata service abuse, URL validation that survives DNS rebinding, egress filtering and testing and detection. It is for application security engineers, cloud and platform engineers and SOC teams, and it contains no payloads or bypass techniques. For the wider picture see the Web Application Attacks Guide.

Key takeaways

  • SSRF is a confused deputy. CWE-918 sits under CWE-441, the unintended proxy: the server makes a request it should not, with network reach and credentials the attacker lacks.
  • Allowlist and build the request yourself. OWASP's rule is to match the host against an allowlist and construct the URL server-side; deny-lists of internal addresses are a fallback because they are bypass-prone.
  • Validate the address you actually connect to. Domain allowlisting alone does not stop DNS rebinding: resolve once, check every resolved IP, then connect only to that IP with redirects off.
  • Treat 169.254.169.254 as a credential store. Block it from application and container network paths, migrate off IMDSv1 and scope instance roles, because metadata service credential harvesting is the payoff in most cloud SSRF.
  • Egress filtering is the backstop. A web tier that can only reach the destinations it needs turns a code flaw into a blocked, logged connection.

How server-side request forgery works

CWE-918 describes a server that receives a URL or similar request from an upstream component and retrieves its contents, but "does not sufficiently ensure that the request is being sent to the expected destination." The request leaves from inside the trust boundary, so it can reach hosts behind firewalls, services bound to localhost and link-local endpoints that never face the internet. The WSTG-INPV-19 test guide adds the second half of the problem: back-end systems often have weak controls because they rely on network isolation, which SSRF removes.

  • Where it occurs: functions that fetch URLs or files named in parameters, headers or cookies; link previews and unfurling; webhooks and callback URLs; import from URL; server-side HTML or PDF rendering that loads referenced resources; XML parsers resolving external entities (CWE-611, which CWE notes is closely related); and AI agent tools that browse or fetch.
  • What it reaches: cloud metadata services, internal admin consoles, databases and caches with HTTP interfaces, container orchestration APIs, internal identity providers and other tenants' endpoints on shared networks.
  • Classification: SSRF was its own OWASP category in 2021, A10:2021, added from the community survey where it ranked first; in the 2025 edition CWE-918 is mapped into A01:2025 Broken Access Control. MITRE ATT&CK records the initial exploitation as T1190 Exploit Public-Facing Application and metadata theft as T1552.005 Cloud Instance Metadata API, which names SSRF in a public-facing proxy as one route.

SSRF variants and why each matters

VariantWhat the attacker getsWhy it matters for defence
Full read SSRFThe fetched response is returned to themDirect theft of metadata credentials and internal data; OWASP A10:2021 says not to send raw responses to clients
Blind SSRFThe request is made but nothing is returned, or it runs later in another workflow such as staff reportsStill reaches state-changing internal endpoints; found only through egress logs and out-of-band testing
Semi-blind SSRFDifferences in errors or timingEnough to map internal hosts and ports (OWASP's first A10:2021 scenario)
Authenticated SSRFSSRF in a feature only signed-in users or admins can reach, such as integrations or webhooksNeeds a cheap account or one stolen session; do not lower severity because login is required
Cloud SSRFRequests to metadata services, cloud-internal endpoints and private APIsTurns a web bug into cloud credentials and lateral movement
Redirect-based SSRFAn allowed destination answers with a redirect to an internal oneValidation is bypassed unless the client refuses redirects; CWE-918 lists a URL library following redirects to file and scp schemes
DNS rebindingA hostname resolves to a public address at check time and an internal one at connect timeDefeats validation that checks the name, not the connected IP
Non-HTTP schemesA fetcher that accepts file, FTP, SMB, SMTP or other schemes reaches local files or other protocolsScheme allowlist of HTTPS (or HTTP and HTTPS) only

Cloud instance metadata services

Every major cloud exposes an instance metadata service at the link-local address 169.254.169.254, reachable from any process on the instance and, unless blocked, from containers on it. It serves instance details and, critically, short-lived credentials for the role or identity attached to the workload. ATT&CK calls 169.254.169.254 the de facto endpoint across providers. This is why metadata service abuse dominates cloud SSRF: one forged request can return keys that work from anywhere.

ProviderEndpointBuilt-in request checkCredentials servedHardening
AWS EC2 metadata service (IMDS)169.254.169.254 (IPv6 fd00:ec2::254 on Nitro instances in IPv6 subnets)IMDSv1: none. IMDSv2: session token obtained with a PUT; PUT requests carrying X-Forwarded-For are rejected; default response hop limit of 1Temporary credentials for the instance profile roleRequire IMDSv2 (httpTokens set to required), disable IMDS where unused, scope the role
Azure Instance Metadata Service169.254.169.254, non-routable, only from within the VMRequests must carry the header Metadata: true and must not carry X-Forwarded-For; not supported behind a proxyManaged identity tokensLocal firewall rules limiting IMDS to the processes that need it; scope the managed identity
Google Cloud metadata servermetadata.google.internal (169.254.169.254)Requests must carry the Metadata-Flavor: Google header; legacy v0.1 and v1beta1 endpoints were shut down on 30 September 2020Service account access tokensLeast-privilege service accounts; on GKE, Workload Identity Federation for GKE rather than node credentials
  • Header and token checks are defence in depth, not a fix. They stop the simplest forged GET, which is exactly what most SSRF bugs produce, but code execution on the host or an SSRF that controls methods and headers gets past them. The OWASP cheat sheet calls IMDSv2 a mitigation for some SSRF instances, not a complete fix.
  • Retire IMDSv1: IMDSv1 is a plain request and response with no token, so any SSRF that can make a GET reaches role credentials. AWS's migration path is to find instances with http-tokens set to optional, update SDKs and agents, watch the CloudWatch MetadataNoToken metric fall to zero, then require IMDSv2 and make it the account default (Amazon Linux 2023 disables IMDSv1 by default). Configuration and enforcement detail sits in the AWS Security Guide.
  • Containers and pods: block workload pods from the node's metadata endpoint with network policy, and give each workload its own identity. Google says to use Workload Identity Federation for GKE "instead of metadata concealment in all situations", because node metadata includes kubelet credentials.
  • Azure note: Microsoft states that "IMDS is not a channel for sensitive data. The API is unauthenticated and open to all processes on the VM", so treat any process that can make arbitrary requests as able to obtain the VM's managed identity token.

The Capital One breach is the reference case: SSRF through a misconfigured web application firewall returned the instance role's credentials, which then listed and copied storage. See the Cloud Workload Identity Guide for scoping the identities behind metadata services.

URL validation for SSRF that holds up

OWASP splits SSRF prevention into two cases. When the application only needs to call known, trusted destinations, use a strict URL allowlist. When it must call arbitrary external destinations (webhooks, previews), an allowlist is impossible and the fallback is a blocklist of internal ranges plus network controls. In both cases the cheat sheet warns that full URLs "are difficult to validate and the parser can be abused", so accept the smallest input possible.

  1. Accept an identifier, not a URL, where you can: a partner ID or a hostname that maps to a server-side configured endpoint. OWASP: "Match the host against an allowlist, and build the request yourself", with scheme, port and path fixed in code.
  2. Parse once with one vetted library and use its output for every later decision. If two parsers could read the host differently, reject the input. OWASP warns that some libraries accept alternative IP encodings (hex, octal, dword, mixed), and CWE-918 lists a CVE where an octal or hexadecimal address format bypassed an SSRF filter.
  3. Allowlist the scheme (HTTPS, or HTTP and HTTPS) and the port.
  4. Resolve, then check every address: resolve the hostname, and refuse if any resolved IPv4 or IPv6 address falls in a blocked range.
  5. Connect to the checked IP: pin the connection to the validated address while keeping the original hostname for the Host header, SNI and certificate verification. A second lookup by the HTTP client is how DNS rebinding wins. Apply the same rule to retries.
  6. Disable redirects, or re-run the whole validation on each hop with a low hop limit.
  7. Return processed data, not raw responses, with tight timeouts, response size limits and generic errors so the fetcher cannot be used to map ports.

A minimal blocklist for the arbitrary-destination case, from the OWASP cheat sheet:

RangeWhy block it
169.254.169.254, metadata.google.internal, metadata.amazonaws.com; IPv6 link-local fe80::/10Cloud metadata services and link-local services
127.0.0.0/8, 0.0.0.0/8, ::1/128Loopback services on the host itself
10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7Private and unique local networks
224.0.0.0/4, ff00::/8Multicast

Extend it with your own internal public ranges, carrier-grade NAT space and cloud provider internal endpoints, and remember the cheat sheet's verdict: "Deny-lists are bypass-prone. Prefer allow-lists."

PHP SSRF and language-level fetchers

PHP SSRF often comes from file functions rather than an HTTP client. The allow_url_fopen directive, on by default and settable only at system level (INI_SYSTEM), lets file functions open URLs through wrappers for HTTP and FTP, and extensions may register more. Disable it in php.ini where the application does not need remote file access, keep allow_url_include off (it is deprecated since PHP 7.4.0), and route all outbound calls through one HTTP client wrapper that enforces the steps above. The same principle applies in every language: find every API that accepts a URL, including image libraries, XML parsers and document converters, and give them no network access or the shared safe client.

Egress filtering for SSRF

OWASP A10:2021 asks for deny-by-default firewall or ACL policy that blocks all but essential intranet traffic, with an owner and lifecycle for each rule and logging of accepted and blocked flows. Outbound request filtering is the SSRF protection that limits the damage when validation fails.

  • Segment the fetchers: run URL-fetching features in a separate service and network segment with no route to internal systems or metadata, as OWASP A10:2021 recommends. See the Network Segmentation Guide.
  • Force egress through a proxy that enforces the destination allowlist or internal-range blocklist and logs every request with the calling workload's identity.
  • Block metadata on the host: host firewall rules or container network policy so only the processes that need IMDS can reach it, as Microsoft suggests for Azure IMDS.
  • Deny cloud-wide by policy: security groups and network policies with no default outbound allow on web tiers.
  • Do not co-locate sensitive services: OWASP advises against hosting other security-relevant services, such as OpenID, on front-facing systems.

Decision guidance

SituationApproachTrade-off
Fixed integrations (payment, partner APIs)Server-side endpoint configuration; user picks an ID, never a URLNew partners need a configuration change
User-supplied but bounded destinations (customer's own tenant domain)Allowlist of domains per tenant plus resolve-and-pinAllowlist maintenance per customer
Arbitrary destinations (webhooks, link previews, AI browsing tools)Isolated fetch service with internal-range blocklist, pinning, no redirects, egress proxy, OWASP proof-of-legitimacy token for webhooksExtra service to run; blocklists still need care
Feature not essentialRemove server-side fetching; fetch in the browser insteadSome functionality lost

Layer the SSRF defences rather than choosing one. Small teams get most of the benefit from one shared HTTP client wrapper, IMDSv1 retired on the AWS metadata service and a default-deny outbound security group. Large estates should run a central egress proxy and fetch service as a platform, so individual teams cannot ship a raw outbound call.

SSRF in Kubernetes and AI infrastructure

  • Admission controller SSRF: admission webhooks are, in the Kubernetes documentation's words, "essentially part of the cluster control-plane", and the API server calls whatever URL a webhook configuration names. Anyone who can create or edit ValidatingWebhookConfiguration or MutatingWebhookConfiguration objects can therefore direct control-plane requests, and policy or admission controllers that fetch external data on admission make outbound calls from a privileged position. Restrict RBAC on those resources to cluster administrators, prefer service references to URLs, and filter control-plane egress. See the Kubernetes Security Guide.
  • Pods and node metadata: a pod that can reach the node's metadata endpoint inherits the node's cloud identity. Block it and use per-workload identity.
  • SSRF in AI infrastructure: LLM frameworks, retrievers and agents fetch URLs chosen by model output or prompt content. Three of the ten observed examples on the CWE-918 page are AI tooling: an LLM toolkit fetching image URLs (CVE-2026-33626, exploited in April 2026 for port scanning), a framework URL retriever following a redirect to local addresses (CVE-2024-3095), and prompt injection that makes an integration fetch arbitrary URLs (CVE-2023-32786). In the OpenAI and Hugging Face breach, agents first reached the internet through SSRF and later took instance role credentials from 169.254.169.254; the response included blocking pod access to instance metadata. Run agent fetch tools through the isolated fetch service, never from hosts holding credentials. See the AI Infrastructure Workload Identity Guide.

Testing for SSRF

  • Inventory URL-consuming features: WSTG-INPV-19 starts with finding every input that is fetched, including headers, cookies, document generators and data processed later by internal workflows.
  • Unit test the validator: feed it alternative IP notations, IPv6 forms, internal hostnames, redirects and names that resolve to blocked ranges, and assert rejection. Keep these cases in the shared library's test suite.
  • Find blind SSRF out of band: point inputs at a listener your team controls and watch for callbacks, and review egress proxy logs during tests.
  • Test rebinding and redirects against staging with a test domain you own, confirming the client connects only to the validated address.
  • Check cloud posture: list instances where IMDSv1 is still allowed and pods that can reach node metadata. See the Penetration Testing Guide for scoping.

Detection and measurement

  • Metadata access by the wrong process: ATT&CK detection DET0001 targets access to metadata endpoints from VMs or containers, covering direct and SSRF patterns. Alert when a web server or application process, rather than the cloud agent or SDK, calls 169.254.169.254.
  • Credentials used off the instance: on AWS, GuardDuty's InstanceCredentialExfiltration findings flag instance role credentials used from outside the instance; correlate CloudTrail source IPs with the owning workload.
  • IMDSv1 calls: CloudWatch MetadataNoToken above zero means IMDSv1 is still in use; MetadataNoTokenRejected after enforcement shows blocked attempts.
  • Egress anomalies: proxy or firewall denials to internal ranges from fetch services, new internal destinations, and many short connections to sequential ports (port scanning through the fetcher).
  • Validator rejections: log blocked destinations with user and feature; a spike from one account is an active probe. See the SIEM Guide.

Metrics:

  1. Share of URL-fetching features routed through the shared safe client or fetch service (target 100%).
  2. Instances with IMDSv1 allowed, and MetadataNoToken trend across the estate.
  3. Workloads with default outbound allow on web and fetch tiers.
  4. Pods able to reach node metadata endpoints.
  5. SSRF findings per quarter from testing and bug bounty, and time to fix.

Implementation roadmap

  1. Find the fetchers: search code for HTTP clients, URL-aware file functions, renderers and XML parsers, and list every feature that takes a URL.
  2. Cut the payoff first: require IMDSv2 or the provider's equivalent protections, block metadata from containers and scope instance roles. Test in audit first: on AWS, watch MetadataNoToken before enforcing; roll back by setting http-tokens back to optional on the affected instances.
  3. Ship the shared safe client with allowlist, resolve-and-pin, scheme and redirect controls, and migrate the highest-risk features to it behind a feature flag.
  4. Isolate arbitrary-destination features (webhooks, previews, AI tools) into a fetch service in its own segment.
  5. Turn on egress filtering in log-only mode, review a full business cycle of flows, then switch to deny by default with named rule owners.
  6. Add tests and detections: validator unit tests in CI, out-of-band tests in each release, and alerts on metadata access and off-instance credential use.

Framework mapping

FrameworkWhere SSRF prevention sits
OWASP Top 10A10:2021 Server-Side Request Forgery; CWE-918 mapped into A01:2025 Broken Access Control
CWECWE-918 (Base), child of CWE-441 confused deputy; related CWE-611 XXE
OWASP WSTGWSTG-INPV-19 Testing for Server-Side Request Forgery
MITRE ATT&CKT1190 Exploit Public-Facing Application; T1552.005 Cloud Instance Metadata API (mitigations M1042, M1037, M1035)
NIST SP 800-53 Rev. 5SI-10 Information Input Validation; SC-7 Boundary Protection and SC-7(5) deny by default; AC-4 Information Flow Enforcement; CM-7 Least Functionality
NIST CSF 2.0PR.IR-01 networks and environments protected from unauthorised logical access
CIS Controls v8.14.4 server firewalls; 12.2 secure network architecture; 13.10 application layer filtering; 16.12 code-level security checks
ISO/IEC 27001:2022 Annex AA.8.20 Networks security; A.8.22 Segregation of networks; A.8.26 Application security requirements; A.8.28 Secure coding

Common failure patterns

  • Validating the name, connecting by name: the hostname passes the check, then the HTTP client resolves it again to an internal address. Pin the validated IP.
  • Following redirects: an allowlisted host redirects inward and the client follows. Turn redirects off.
  • Regex blocklists: pattern matching on URL strings misses alternative encodings and IPv6; OWASP A10:2021 says not to rely on deny lists or regular expressions.
  • Open egress plus IMDSv1: the combination that made the Capital One breach possible, and still common on older instances.
  • Over-privileged instance roles: the metadata service only returns what the role can do; broad storage and IAM permissions turn one request into a data breach.
  • Forgotten fetchers: PDF generators, image resizers and AI tools added after the security review, outside the shared client.

Practitioner checklist

  • Inventory every feature and library that fetches a URL, including renderers, XML parsers and AI agent tools.
  • Replace user-supplied URLs with server-side configured endpoints wherever destinations are known.
  • Route remaining outbound calls through one safe client: scheme allowlist, single parser, resolve and check every IP, pin the connection, no redirects.
  • Block metadata, loopback, link-local, private and multicast ranges for arbitrary-destination features.
  • Run webhooks, previews and agent browsing in an isolated fetch service with no route to internal systems or metadata.
  • Require IMDSv2 on AWS, retire IMDSv1 using MetadataNoToken, and limit Azure and Google metadata access to the processes that need it.
  • Block pods from node metadata and give each workload its own scoped identity.
  • Apply deny-by-default egress on web and fetch tiers through a logging proxy.
  • Disable allow_url_fopen in PHP where remote file access is not needed.
  • Alert on metadata access by application processes and on instance credentials used off the instance.

Standards and references

Related NHI Mgmt Group resources: Web Application Attacks Guide · AWS Security Guide · Cloud Workload Identity Guide · Network Segmentation Guide · Kubernetes Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Written and reviewed by Lalit Choda, NHI Mgmt Group. Last updated 18 October 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org