loader
critical risk OSI Layer 7 / Server egress and filesystem current

SSRF and Path Traversal

A feature that fetches a resource accepts an untrusted destination, letting an attacker use the server's network position or filesystem access as their own.

Defender-oriented briefing. This page describes behavior, observable signals, prevention and response. Operational attack instructions are intentionally excluded.

How it works

The application takes a location from the request — a URL to fetch or a path to read — and acts on it without constraining where it may point. The server's privileges, not the user's, determine what comes back.

The server as a confused deputy

Both flaws in this article share a shape: the application accepts a destination from the user and then travels there using its own authority. The attacker cannot reach the internal network or the filesystem, but the server can, and the server has been persuaded to go on their behalf.

This is why severity is so often underestimated at review time. The feature looks like a fetch or a file read, and the response may be discarded. The value to an attacker is not the response — it is reaching things that are only reachable from inside.

That position is usually far more privileged than the perimeter suggests. Internal services frequently assume network location implies authorisation, and expose administrative interfaces with no authentication because "only internal systems can reach them". SSRF makes the application an internal system that takes requests from the internet.

Cloud metadata, and why SSRF became critical

SSRF was a moderate-severity finding until cloud environments made a credential-issuing endpoint reachable over plain HTTP from every instance, at a fixed address, with no authentication.

A server-side fetch that can be pointed at that address returns credentials for the instance role. Depending on how generously that role is scoped, the outcome ranges from reading one bucket to controlling the account. This single fact turned SSRF into a first-order concern.

Newer metadata services require a token obtained by a request method that a naive fetch will not produce, which mitigates the simplest cases and is worth enforcing where the option exists. It is a mitigation rather than a boundary: it raises the bar for a plain GET-based SSRF but does not help where the attacker controls method or headers.

Why URL validation keeps failing

Blocking URLs that look internal is the intuitive fix and has a long record of being bypassed, because the check and the connection interpret the address differently.

Loopback and private ranges have many textual representations — decimal, octal, hexadecimal, IPv6-mapped forms, and abbreviations. A blocklist matching one string misses the others. Domain names under attacker control can resolve to private addresses, so a hostname check passes and the connection still lands internally. And where validation resolves the name once and the connection resolves it again, the answer can differ between the two lookups.

Redirects are the most frequently missed case. A permitted host returns a redirect to an internal address, and an HTTP client that follows redirects by default arrives there without any further check.

The design that holds inverts the model: do not accept a location at all. Accept an identifier and map it server-side to a destination you control. Where the product genuinely requires arbitrary URLs — a webhook tester, a link preview — allow-list schemes and hosts, disable automatic redirect following so each hop is validated explicitly, and resolve the name yourself then connect to the address you validated rather than to the name.

Path traversal

The filesystem variant is the same mistake against a different namespace. A parameter names a file, the application joins it to a base directory, and traversal sequences walk out of that directory into configuration, credentials or source.

Naive filtering fails for the same reason as URL filtering: many encodings map to the same path. Stripping one traversal sequence is defeated by nesting, since a single pass over a doubled sequence reconstructs it. Encoded separators, mixed separators on platforms that accept both, and Unicode forms that normalise late all produce the same result.

Canonicalise first, then check. Resolve the path to its absolute form, then verify that the result is genuinely inside the intended base directory. Checking before resolution checks a string rather than a location.

Better still, do not accept paths. Map an identifier to a file server-side and store uploads under generated names, so the request never contains a path at all.

Containment

Both flaws are worth defending twice, because the application-layer fix is subtle enough to get wrong.

  • Egress filtering that prevents application hosts from reaching private ranges, loopback and metadata addresses — this neutralises most SSRF regardless of application-level validation.
  • Internal services requiring authentication rather than inferring trust from network position, so arriving from inside is not sufficient.
  • Instance roles scoped to what the workload genuinely needs, limiting the value of any credential that is retrieved.
  • Filesystem confinement so the process cannot read outside its content directory even if a traversal succeeds.
  • Outbound connection logging, since unusual destinations are frequently the first evidence and are otherwise invisible.

Also known as

SSRF directory traversal LFI RFI path traversal

What defenders may observe

  • Server connects to private or link-local addresses
  • Cloud metadata endpoints appear in outbound logs
  • Redirect chains end somewhere unexpected
  • Traversal sequences or encoded separators in path parameters
  • Access to configuration or system files outside the content directory

Prevention and mitigation

  • Accept an identifier and map it server-side to a destination, rather than accepting a location
  • Where arbitrary URLs are required, allow-list schemes and hosts and re-validate after every redirect
  • Resolve the hostname and check the resulting address before connecting, then connect to that address
  • Block private, loopback, link-local and metadata ranges at network egress
  • Use opaque identifiers instead of file paths; canonicalise and confine to a base directory when unavoidable
  • Run the service with minimal filesystem and network reach

Initial response priorities

  • Contain the vulnerable route or feature.
  • Preserve requests, traces and affected records.
  • Fix the root control failure, test adjacent paths and rotate exposed secrets.

Use your approved incident-response plan and adapt decisions to your environment. This is educational guidance, not a substitute for live incident leadership.

Authoritative references