Server-Side Request Forgery (SSRF) is the risk that an attacker tricks your server into making a request on their behalf to a destination they choose, and it ranks number ten on the OWASP Top 10 (2021). It is the only category added purely on the strength of the community survey, where practitioners ranked it far higher than raw incidence data would, because SSRF has become the signature vulnerability of cloud-native systems. When an application fetches a URL supplied by a user, the attacker can redirect that fetch inward, reaching internal services, cloud metadata endpoints, and administrative interfaces that were never meant to face the internet, using the server's own trusted position as the launch point.
What OWASP A10 actually covers
SSRF occurs whenever a web application retrieves a remote resource without validating the user-supplied destination. The typical trigger is a feature that accepts a URL, such as a webhook, a document importer, an image proxy, a link previewer, or a PDF generator, and then fetches it server-side. Because the request originates from inside your network, it inherits the trust boundary of the server: firewalls that block outside traffic wave it through, and internal services that assume any caller is friendly answer freely. The category maps primarily to CWE-918 (server-side request forgery). Attackers use it to scan and reach internal hosts, to read cloud instance metadata and steal credentials, to hit services bound to localhost, and sometimes to escalate into remote code execution when an internal service is itself exploitable.
Why it ranks number ten
A10 carries a relatively low incidence rate but an unusually high practitioner concern, which is precisely why it was promoted from a subsection into its own Top 10 category. The gap reflects the cloud reality that a single SSRF can be devastating out of proportion to how often it appears in scans. In a modern deployment, the server sits amid a mesh of internal microservices and a metadata endpoint that hands out identity credentials to anything that asks from the right place. SSRF is the key that unlocks that soft interior, so security teams weight it heavily even though it is not the most common flaw by volume.
Real-world examples
The 2019 Capital One breach is the defining SSRF incident. A misconfigured web application firewall was abused via SSRF to reach the cloud instance metadata endpoint at address 169.254.169.254, retrieve temporary IAM credentials assigned to the server's role, and then use those credentials to read storage buckets holding the data of roughly 100 million people. No password was cracked; the server was simply persuaded to ask the metadata service for its own keys. CVE-2021-26855 shows SSRF as a pre-authentication entry point: known as ProxyLogon, it is a server-side request forgery flaw in Microsoft Exchange, rated CVSS 9.8, that let unauthenticated attackers send crafted requests the server would relay internally, and it was chained with other bugs to seize control of thousands of Exchange servers worldwide. Both cases share the A10 fingerprint: the server made a request the attacker controlled, against a target the attacker chose.
Vulnerable versus fixed code
The classic SSRF sink is a handler that fetches whatever URL a user hands it.
# VULNERABLE: fetches any URL, including internal and metadata addresses
import requests
def fetch_preview(url):
# attacker sends http://169.254.169.254/latest/meta-data/iam/...
resp = requests.get(url, timeout=5)
return resp.text
# FIXED: allowlist scheme, resolve host, block internal ranges
import ipaddress, socket
from urllib.parse import urlparse
import requests
def fetch_preview(url):
parts = urlparse(url)
if parts.scheme not in ("http", "https"):
raise ValueError("scheme not allowed")
ip = ipaddress.ip_address(socket.gethostbyname(parts.hostname))
if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
raise ValueError("destination not allowed")
return requests.get(url, timeout=5, allow_redirects=False).text
The fixed version restricts the scheme, resolves the hostname to an IP, and rejects any address in a private, loopback, link-local, or reserved range, which is what blocks the metadata endpoint and internal hosts. Disabling redirects matters too, because an allowed public URL can otherwise redirect to an internal one after the check has passed.
Prevention checklist
- Validate and allowlist the destinations your server may fetch, by scheme and by host, rather than accepting arbitrary URLs.
- Resolve the hostname and block private, loopback, link-local, and reserved IP ranges, including the cloud metadata address.
- Disable or tightly restrict HTTP redirects so a safe URL cannot bounce to an internal one after validation.
- Enforce network-layer egress controls so application servers cannot reach internal services they do not need.
- Require authentication on internal services rather than trusting any caller inside the perimeter.
- Use the cloud provider's hardened metadata service (for example, requiring session tokens) to blunt credential theft.
- Never send raw responses from server-side fetches back to the client unfiltered, which limits blind SSRF leakage.
- Log and alert on outbound requests to unexpected internal destinations, tying into your A09 monitoring.
How Safeguard helps
SSRF is a runtime behavior, so Safeguard's DAST engine probes URL-accepting features the way an attacker would, attempting to redirect server-side fetches toward internal and metadata destinations and flagging handlers that lack allowlisting or range blocking. When the flaw originates in a vulnerable HTTP-client or URL-parsing library rather than your own handler, the SCA engine identifies the component and its advisory, and Auto-Fix opens the upgrade pull request. Griffin AI ties the two together, explaining whether the vulnerable path is reachable and what the concrete fix looks like. To see how reachability-first triage differs from volume-based scanners, compare Safeguard against Snyk.
Frequently Asked Questions
What makes SSRF so dangerous in cloud environments specifically?
Cloud instances expose a metadata endpoint at a fixed internal address that returns configuration and, critically, temporary credentials for the identity role attached to the instance. An attacker who can make the server request that endpoint often walks away with keys to the wider cloud account, as happened at Capital One. On top of that, cloud deployments run dense meshes of internal microservices that assume any internal caller is trusted, so a single SSRF becomes a pivot into the whole environment.
What is the difference between blind and non-blind SSRF?
In non-blind SSRF the response from the forged request is returned to the attacker, so they can directly read internal pages or metadata. In blind SSRF the response is not returned, but the attacker can still confirm the request happened through timing, error differences, or an out-of-band callback to a server they control. Blind SSRF is harder to exploit but far from harmless, because it still enables internal port scanning and can trigger state-changing actions on internal services.
Is validating the URL with a blocklist of internal IPs enough?
Blocklists alone are fragile. Attackers bypass them with alternate IP encodings, DNS names that resolve to internal addresses, DNS rebinding that changes the answer between the check and the fetch, and redirects from an allowed host to an internal one. The robust approach is to allowlist permitted destinations, resolve the host and validate the actual IP against private and reserved ranges, disable redirects, and enforce network egress controls so a bypass has nowhere useful to go.
How is SSRF different from ordinary request forgery like CSRF?
Cross-site request forgery tricks a victim's browser into sending an authenticated request to your application, so the confused party is the user's client. SSRF tricks your server into sending a request to a destination the attacker picks, so the confused party is your backend. They share the word forgery but point in opposite directions, and SSRF is generally more severe because the server sits inside the trust boundary that internal services rely on.
Ready to find SSRF before an attacker does? Start scanning at app.safeguard.sh/register, or read the setup guide at docs.safeguard.sh.