logo svg
logo

November 4, 2026

Updated: November 4, 2026

What Is SSRF? Server-Side Request Forgery Explained

How SSRF works, blind SSRF, AWS IMDSv1 vs IMDSv2, real cases, OWASP 2025 placement, lab-safe testing and layered prevention.

Mohammed Khalil

Mohammed Khalil

Featured Image

Server-side request forgery (SSRF) is a vulnerability in which an attacker makes a server send requests to a destination the attacker chooses. Because the request comes from inside your environment, it can reach internal services, admin panels and cloud metadata endpoints that the attacker could never reach directly. This guide explains how an SSRF attack works, why AWS IMDSv1 made SSRF a credential-theft problem and how IMDSv2 changes that. It also covers what the public record says about the 2019 Capital One breach, blind SSRF, safe testing and the controls that prevent it.

What Is SSRF?

SSRF definition: Server-side request forgery is a flaw where an application fetches a URL or address that a user can influence, without restricting where that request may go. The attacker cannot reach the target directly, so they borrow the server's network position, identity and trust to reach internal or protected systems for them.

MITRE catalogs the weakness as CWE-918: Server-Side Request Forgery. The core problem is not "a bad URL." It is a server that makes outbound requests on a user's behalf without a firm rule about which destinations are allowed.

SSRF usually hides in ordinary features that fetch something from a URL:

Any of these features is safe when it can only reach the destinations it was built for. It becomes SSRF when the destination is open-ended.

SSRF vs CSRF

The names are similar, and people often confuse them. The difference is whose request is forged and who gets fooled.

SSRF (server-side request forgery)CSRF (cross-site request forgery)
Who sends the forged requestYour serverThe victim's browser
Who is trickedThe application's back endA logged-in user's session
What the attacker gainsAccess to systems that trust the server's network position or identityActions performed with the victim's cookies or session
Typical targetsInternal APIs, admin interfaces, databases, cloud metadata servicesState-changing actions such as changing an email address or making a transfer
Core fixRestrict outbound destinations; isolate the fetcherAnti-CSRF tokens, SameSite cookies, origin checks

How an SSRF Attack Works

An SSRF attack follows the same shape no matter which feature is vulnerable:

  1. The attacker finds a feature that fetches a URL. A webhook field, an import box or an API parameter such as url, callback or imageUrl is a common starting point.
  2. The attacker supplies a destination the developer did not expect. Instead of a public website, the value points at something only the server can reach: a loopback address, an internal hostname, a private IP range or a cloud metadata address.
  3. The server makes the request with its own network position and identity. Firewalls that block the internet from internal systems usually allow traffic from the application server, because that server is trusted.
  4. The response, or a side effect, comes back to the attacker. In basic SSRF the fetched content is returned in the page or API response. In blind SSRF the attacker sees only timing, errors or a side effect.
SSRF attack flow: an attacker sends a URL to a vulnerable web app, which requests internal services and cloud metadata

The reason SSRF matters so much is the trust boundary. Most networks are built so that the internet cannot reach internal admin tools, databases or metadata services, while application servers can. SSRF turns the application server into a relay across that boundary.

What can SSRF expose?

Target reached through SSRFWhy the server can reach itTypical impact
Loopback services on the same hostAdmin or debug interfaces often listen only on localhostAccess to management functions that assume only local callers
Internal APIs and microservicesService-to-service traffic is often unauthenticated inside a VPCData reads, unintended actions, lateral movement
Databases, caches and search clusters with HTTP interfacesBound to private addresses and trusted by network locationData exposure or modification
Cloud instance metadata servicesLink-local endpoint reachable from every instance by designInstance details and, on AWS with IMDSv1 allowed, temporary IAM role credentials
Internal network rangesThe server sits on networks the attacker cannot seeHost and port discovery from the server's vantage point
Third-party systemsThe request appears to come from your IP addressesAbuse attributed to your organization; bypass of partner IP allowlists

Impact depends on what the vulnerable server can reach and what those systems trust. An SSRF in an isolated fetcher with no internal routes is a low-severity finding. The same bug on a server with broad network access and an IAM role attached can be critical.

Types of SSRF

Testers and defenders usually group SSRF by how much feedback the attacker gets:

The vulnerable parameter does not have to be a full URL. Applications that accept a hostname, a path that gets appended to an internal base URL, or a URL embedded inside JSON, XML or a document can all produce SSRF.

Blind SSRF Explained

Blind SSRF happens when an application can be made to send a back-end request to an attacker-chosen destination, but the response never reaches the attacker. A webhook that fires and reports only "saved" is a typical example.

Because nothing comes back, blind SSRF is confirmed out of band. The tester supplies the address of a server they control and watches it for incoming connections. PortSwigger's Web Security Academy notes that seeing only a DNS lookup, without the follow-up HTTP request, often means the application tried to connect but outbound HTTP was filtered while DNS was allowed. The two signals mean different things, and a good report says which one was observed.

Blind SSRF is usually lower impact than basic SSRF because the attacker cannot read internal responses. It is still worth fixing:

SSRF and Cloud Metadata: AWS IMDSv1 vs IMDSv2

Cloud metadata services are the reason SSRF moved from "medium" to "critical" in many cloud environments.

Every Amazon EC2 instance can query the Instance Metadata Service (IMDS) at the link-local address 169.254.169.254 (and, when enabled on Nitro instances in IPv6 subnets, [fd00:ec2::254]), according to AWS's IMDS documentation. IMDS returns instance details. If an IAM role is attached to the instance, it also delivers the temporary credentials for that role, which AWS calls EC2 Role credentials. Software on the instance uses those credentials to call AWS APIs.

That design assumes only code running on the instance can reach the endpoint. SSRF breaks the assumption, because the vulnerable application is code running on the instance.

IMDSv1: one simple request

IMDSv1 is a request/response method: a plain HTTP GET to the metadata path returns the data. There is no session, token or required header. An SSRF that lets an attacker make the server send a basic GET, which is the most common SSRF capability, is enough to read metadata. On an instance with a role attached, that includes the role's temporary credentials. Whatever that role is allowed to do in AWS, the attacker can now attempt from outside.

IMDSv2: a session token first

IMDSv2 is session-oriented. AWS documents these requirements:

When AWS announced the IMDSv2 enhancements on November 19, 2019, it framed them as defense in depth against open web application firewalls, open reverse proxies and SSRF. AWS explained that most open WAFs rarely support PUT requests, and that combining PUT with a session token protects against "the vast majority of SSRF vulnerabilities." It did not claim all of them.

IMDSv1IMDSv2
Request modelSingle request and responseSession: PUT for a token, then GET with the token
Required HTTP method to startGETPUT
Required headersNoneTTL header on PUT; token header on every GET
Behavior behind a forwarding proxyWorks through many proxiesToken PUT rejected if X-Forwarded-For is present
Off-instance token useNo token existsToken is instance-specific; default PUT response hop limit is 1
Exposure to a basic GET-only SSRFMetadata and role credentials readableBlocked; the request has no token
Can it be the only version allowedIt can be disabledYes: set HttpTokens to required ("IMDSv2 only")
AWS IMDSv1 vs IMDSv2: v1 answers a plain GET, v2 needs a PUT session token with hop limit 1 and rejects proxies

"Allowed" is not "required"

The most important operational detail is that IMDSv2 only helps when IMDSv1 is turned off. The AWS user guide states that by default an instance can use either IMDSv1 or IMDSv2, or both. The effective setting comes from a precedence chain: launch parameters override account-level defaults, which override the AMI setting. AMIs registered with ImdsSupport set to v2.0 launch instances that require IMDSv2, and AWS notes that Amazon Linux 2023 disables IMDSv1 by default. But a launch template that explicitly sets tokens to optional still produces an instance that accepts IMDSv1.

In other words, an organization can believe it "uses IMDSv2" while many instances still answer IMDSv1 requests. That is why cloud penetration tests check the actual HttpTokens value across the fleet, not the policy document.

What IMDSv2 does not fix

IMDSv2 is a strong control, but it is not an SSRF fix:

Google Cloud and Azure metadata services

Other clouds use a different guard: a required static header plus proxy detection. Google Cloud's metadata server denies requests that lack the Metadata-Flavor: Google header and automatically rejects requests that contain X-Forwarded-For. Azure Instance Metadata Service requires the Metadata: true header and rejects requests that contain X-Forwarded-For.

These checks stop SSRF bugs that can only control the URL. They do not stop SSRF bugs that can also set headers. AWS argued in its 2019 post that a PUT-plus-token design is always strictly more effective than requiring only a static header.

Real-World SSRF Examples

The 2019 Capital One breach: what the primary record says

The Capital One case is the incident most people associate with SSRF and cloud metadata. It is worth separating what the official record states from what has been reconstructed since.

What the U.S. Department of Justice and the OCC documented:

What the primary record does not say: The DOJ announcements and the OCC order do not use the term "server-side request forgery," and they do not describe the request chain step by step. The widely repeated explanation is that a request through the misconfigured firewall reached the instance metadata service and obtained role credentials, which were then used to read storage. That explanation comes from later technical analysis of the charging documents, not from a court finding. Treat it as a well-supported industry reconstruction.

Why the case still belongs in an SSRF guide: The documented facts match the conditions SSRF defenses exist to break. A server-side component on the network edge could be made to reach resources it should not. Cloud credentials sat behind it, with broad access to stored data. Detection came from an outside tip, not internal alerting. Four months after the arrest, AWS published its IMDSv2 enhancements and explicitly named open firewalls, reverse proxies and SSRF as the threats they address.

CVE-2021-26855: Microsoft Exchange Server (ProxyLogon)

CVE-2021-26855, published in the National Vulnerability Database on March 3, 2021, affects on-premises Microsoft Exchange Server. NVD maps it to CWE-918. CISA added it to its Known Exploited Vulnerabilities catalog, and NVD records the KEV addition date as November 3, 2021. It shows that SSRF is not only a cloud problem: in an appliance or server product, an SSRF that reaches back-end components can be the first link in a remote code execution chain.

CVE-2024-21893: Ivanti Connect Secure and Policy Secure

CVE-2024-21893 is an SSRF in the SAML component of Ivanti Connect Secure (9.x, 22.x), Ivanti Policy Secure (9.x, 22.x) and Ivanti Neurons for ZTA. It allows an attacker to access certain restricted resources without authentication. NVD lists it as published on January 31, 2024, the same day CISA added it to the KEV catalog. It is a reminder that SSRF often sits in authentication and federation code that parses externally supplied data.

CVE-2024-34351: Next.js Server Actions

CVE-2024-34351 is an SSRF in Next.js Server Actions. If an attacker modifies the Host header, and the app is self-hosted, uses Server Actions and performs a redirect to a relative path starting with /, the attacker may be able to make requests that appear to come from the Next.js server itself. It was fixed in Next.js 14.1.1. Our Next.js security testing guide covers this class of framework-level issue in more depth.

CaseDate (primary record)Where the SSRF livedLesson
Capital OneArrest July 29, 2019; OCC penalty August 6, 2020Misconfigured web application firewall in AWS (DOJ wording)Edge components with cloud roles need egress limits, IMDSv2 and least privilege
CVE-2021-26855NVD published March 3, 2021On-premises Exchange ServerSSRF can open a path to remote code execution
CVE-2024-21893NVD published and KEV added January 31, 2024SAML component of a VPN gatewayFederation and auth code is SSRF attack surface
CVE-2024-34351NVD published May 14, 2024Framework handling of Host header and redirectsTrusting request headers to build internal URLs creates SSRF

Where SSRF Sits in the OWASP Top 10 (2021 and 2025)

In the 2021 edition, SSRF had its own category, A10:2021 Server-Side Request Forgery.

The OWASP Top 10:2025 no longer lists SSRF separately. The introduction states that SSRF "has been rolled into" A01:2025 Broken Access Control. The A01:2025 category page names CWE-918 Server-Side Request Forgery (SSRF) among its notable CWEs and lists 40 mapped CWEs in total. The 2025 tenth slot went to a new category, A10:2025 Mishandling of Exceptional Conditions.

The move does not mean SSRF matters less. It reflects how OWASP now frames the problem: an application lets a user reach a resource they should not reach, which is an access control failure. For testing and reporting, SSRF remains its own weakness, CWE-918, with its own test cases and fixes. Our overview of the most common web vulnerabilities shows where SSRF fits among the other classes testers find most often.

Our OWASP Top 10 2025 guide explains every category in the current list, including A01 Broken Access Control.

How Penetration Testers Check for SSRF (Lab-Safe)

SSRF testing has to be careful by design. The whole point of the bug is that the server reaches places it should not, so a careless test can touch production systems, internal services or cloud credentials. Professional testing follows a few rules:

The workflow below is a method, not a payload list.

Step 1: Map every place the server fetches something

Testers inventory features and parameters that cause outbound requests: webhook URLs, import and preview features, document renderers, integration settings, and API fields with names like url, uri, callback, redirect, feed, image or host. In white-box work, code review finds the actual sinks, meaning calls to HTTP client libraries, headless browsers, XML parsers and file fetchers that receive user-influenced input.

Step 2: Establish a baseline with example.com

The tester supplies a harmless public destination and observes what the application does. An illustrative request to a hypothetical link-preview API looks like this:

text
POST /api/v1/link-preview HTTP/1.1
Host: app.example.test
Content-Type: application/json

{"url": "https://example.com/"}

If the response contains the title of the example.com page, the feature fetches content server-side and returns it. That is the precondition for basic SSRF, not proof of a vulnerability. The baseline also shows normal timing, error messages and response sizes, which later comparisons need.

Step 3: Confirm server-side fetching with a controlled callback

For blind or partial cases, the tester uses an out-of-band interaction server they control. Burp Collaborator is common in commercial testing, and the open-source interactsh project is a self-hostable option. The tester generates a unique, single-use hostname for each test, such as https://<unique-id>.<tester-callback-domain>/, and submits it.

The evidence is what arrives at the callback server:

Signal at the callback serverWhat it suggestsNext step
HTTP request from the application's egress IPServer-side fetch to arbitrary external hosts confirmedRecord source IP, headers and user agent; assess what else the server can reach
DNS lookup only, no HTTPThe server resolved the name, but outbound HTTP may be filteredReport as partial; check egress rules before rating impact
Request from a third-party IP or a link scannerSomething other than the application fetched the URLDo not report as SSRF without further proof
Nothing at allNo outbound fetch, or the fetch is restrictedCheck for queued or delayed processing before concluding

Unique identifiers per test matter. They tie each interaction to one parameter and one timestamp, which avoids false positives from link scanners and caches.

Step 4: Test reachability in a lab, not against production internals

Whether the server can reach internal destinations is the real impact question. Mature programs answer it without touching production internals:

Our AWS penetration testing guide explains how this cloud configuration review fits into a wider AWS assessment, including IAM and metadata service checks under AWS's testing policy.

Step 5: Report evidence, impact and a retest plan

A useful SSRF finding includes the vulnerable parameter, the baseline and callback evidence with timestamps, the egress IP, and what the server could reach. It also needs a realistic impact statement that accounts for IMDS configuration and role permissions, plus specific fixes. After remediation, the same callback test is repeated to confirm that the destination is now refused.

How to Prevent SSRF

No single control prevents SSRF. The reliable approach is layered: restrict destinations in code, back that up in the network, and limit what a successful request could reach in the cloud. The OWASP SSRF Prevention Cheat Sheet is the best single reference and underpins most of the advice below.

Six layers of SSRF prevention: design, allowlists, safe parsing and DNS, egress controls, IMDSv2 and least privilege, detection

1. Do not fetch user-supplied URLs when you can avoid it

The strongest fix is design. If users choose from a known set of partners, accept an identifier and map it to a URL on the server. If users upload an avatar, accept a file upload instead of an image URL. If a feature only needs a domain name, do not accept a full URL with a scheme, port and path.

2. Allowlist destinations

When the application only needs to reach known systems, maintain an allowlist of exact hostnames, schemes and ports, and refuse everything else. OWASP's guidance is blunt: deny-lists are bypass-prone, so prefer allowlists. Blocklists of "bad" addresses fail because the same internal destination can be written in many ways.

When users genuinely need to supply arbitrary external URLs, as with customer webhooks, OWASP recommends combining a blocklist of internal and special ranges with a proof-of-ownership step. In that step, the destination must return a token your platform issued before you send it real traffic.

3. Parse once, then build the request yourself

URL parsing is where many SSRF defenses fail. Common pitfalls:

The safest pattern is to validate the input into a small set of parts (an allowlisted host, a fixed scheme and port) and construct the outgoing request from those parts. Do not pass the user's original string to the HTTP client.

4. Resolve, validate every address, then connect to that address

For features that must accept external destinations, check the resolved IP addresses, not just the hostname, and then connect to an address you validated. The Python sketch below is illustrative, not a drop-in library. It shows the logic: allowlist the host, reject credentials and unexpected ports, resolve every address and refuse anything that is not public.

python
import ipaddress
import socket
from urllib.parse import urlsplit

ALLOWED_HOSTS = {"api.partner.example", "images.partner.example"}

def validated_target(url: str) -> tuple[str, list[str]]:
    parts = urlsplit(url)
    if parts.scheme != "https" or parts.hostname not in ALLOWED_HOSTS:
        raise ValueError("destination not allowed")
    if parts.username or parts.password or parts.port not in (None, 443):
        raise ValueError("unexpected URL components")
    infos = socket.getaddrinfo(parts.hostname, 443, proto=socket.IPPROTO_TCP)
    addresses = sorted({host for _, _, _, _, (host, *_) in infos})
    for address in addresses:
        ip = ipaddress.ip_address(address)
        if ip.version == 6 and ip.ipv4_mapped:
            ip = ip.ipv4_mapped
        if not ip.is_global:
            raise ValueError("destination resolves to a non-public address")
    return parts.hostname, addresses

The calling code should then connect to one of the returned addresses, keep the original hostname for the Host header, TLS SNI and certificate validation, set short timeouts and disable redirects. Doing this correctly in every HTTP client is hard, which is why the network controls below matter.

5. Control egress at the network layer

Application checks fail. Network controls catch what they miss:

6. Harden cloud metadata and identity

bash
aws ec2 modify-instance-metadata-options \
  --instance-id i-0123456789abcdef0 \
  --http-tokens required \
  --http-put-response-hop-limit 1

7. Detect SSRF attempts and abuse

Security testing belongs in the development process too. A secure SDLC adds SSRF to threat models for any feature that fetches remote content and adds tests that prove disallowed destinations are refused.

SSRF prevention checklist

LayerControlHow to verify
DesignAccept identifiers or uploads instead of URLs where possibleFeature review: list every user-influenced fetch
ApplicationExact allowlist of host, scheme and port; build the request from validated partsUnit tests that disallowed hosts, schemes and ports are refused
ApplicationDisable redirects; reject parser disagreement; allow only httpsTests with redirecting and malformed inputs in a lab
ResolutionResolve, validate every address, connect to the validated addressLab test with a hostname that resolves to a private canary
NetworkEgress proxy or default-deny outbound rules; metadata and private ranges blockedCallback test from the app subnet to a non-allowlisted host fails
CloudHttpTokens required, hop limit 1, account default and enforcement onImdsV1Enabled sum is zero; describe-instances shows required
IdentityLeast-privilege instance roles; ec2:RoleDelivery 2.0 conditionIAM review of each role attached to internet-facing compute
DetectionOutbound fetch logging and alerts on private and metadata destinationsTrigger a test event and confirm the alert fires

Frequently Asked Questions

What is SSRF in simple terms?

SSRF is when an attacker gets your server to make a web request for them. The attacker picks the destination, and the server sends the request from inside your network with its own trust and identity. That lets the attacker reach internal systems, such as admin pages or cloud metadata, that are blocked from the internet.

What is the difference between SSRF and CSRF?

In SSRF the forged request comes from your server, and the target is internal systems that trust that server. In CSRF the forged request comes from a victim's browser, and the target is actions the logged-in user is allowed to perform. SSRF is fixed by restricting where the server can send requests. CSRF is fixed with anti-CSRF tokens, SameSite cookies and origin checks.

What can an SSRF vulnerability expose?

Anything the vulnerable server can reach and that trusts it: localhost admin interfaces, internal APIs, databases and caches with HTTP interfaces, internal network ranges and cloud metadata services. On AWS instances that still allow IMDSv1 and have an IAM role attached, that can include the role's temporary credentials.

How do you prevent server-side request forgery?

Avoid fetching user-supplied URLs where possible. Otherwise, allowlist exact destinations, build the outgoing request from validated parts, disable redirects, validate the resolved IP address you connect to, block internal and metadata ranges at an egress proxy, require IMDSv2, and keep cloud roles least-privileged.

Is SSRF still in the OWASP Top 10?

Yes, but not as its own category. SSRF was A10:2021. In the OWASP Top 10:2025 it has been rolled into A01:2025 Broken Access Control, which lists CWE-918 among its mapped weaknesses.

Does IMDSv2 stop SSRF?

No. IMDSv2 protects the AWS metadata service from most SSRF bugs, because a typical SSRF cannot perform the PUT token handshake, and proxied requests are refused a token. It does not protect internal APIs or other services, and it only helps when IMDSv1 is disabled on the instance.

What is blind SSRF?

Blind SSRF is when the server makes the attacker-chosen request but never returns the response. It is detected out of band: the tester supplies a unique address on a server they control and watches for the incoming DNS lookup or HTTP request.

Next Step: Find SSRF Before Someone Else Does

SSRF is easy to introduce and easy to miss. Every new webhook, preview or import feature adds another place where the server fetches something on a user's behalf. The checks that matter are the ones that prove the real impact: which destinations the server can reach, whether the instance still answers IMDSv1, and what the attached role can do.

DeepStrike's web application penetration testing services combine automated discovery with manual testing aligned to the OWASP Top 10. Only vulnerabilities validated through exploitation are reported, with actionable remediation steps. For workloads in AWS, Azure or GCP, our cloud penetration testing services test IAM misconfigurations and privilege escalation paths, and map cloud-native attack techniques to MITRE ATT&CK Cloud, the context that decides whether an SSRF is a nuisance or a breach. To scope a test, contact DeepStrike.

About The Author

Mohammed Khalil is a Cybersecurity Architect at DeepStrike, specializing in advanced penetration testing and offensive security operations. With certifications including CISSP, OSCP, and OSWE, he has led numerous red team engagements for Fortune 500 companies, focusing on cloud security, application vulnerabilities, and adversary emulation. His work involves dissecting complex attack chains and developing resilient defense strategies for clients in the finance, healthcare, and technology sectors.

Sources and References

background
Let's hack you before real hackers do

Stay secure with DeepStrike penetration testing services. Reach out for a quote or customized technical proposal today

Contact Us