TidyURLs
Go to Tools
BLOG
The TidyURLsJournal

Practical guides, tutorials, and insights about URLs, SEO, web development, and online marketing. Learn, troubleshoot, and get the most of the web.

Back to the Journal
TidyURLs Journal

SSRF Vulnerability Explained: What Happens When a Server Fetches User URLs?

Practical insights, clear explanations, and useful ideas for understanding the web.

October 25, 20269 min read6 topics
SSRF Vulnerability Explained: What Happens When a Server Fetches User URLs?
Explore the details
#SSRF#web security#URL fetching#DNS rebinding#cloud security#OWASP
October 25, 20269 min read

A feature that fetches a URL entered by a user can seem harmless: a preview generator loads an image, an import tool retrieves a document, or a webhook tester checks a destination. But the request comes from your server, not the user's browser. If the destination is insufficiently controlled, an attacker may use the server's network access to reach services that are not publicly accessible. This is a server-side request forgery (SSRF) vulnerability.

This guide explains how SSRF works, why private IP restrictions alone can fail, and how DNS rebinding, redirects, and cloud metadata affect URL-fetching designs. It uses a fictional, isolated lab scenario and focuses on defensive implementation.

Key takeaways

  • SSRF happens when an application makes a server-side request to a destination that an attacker can influence.
  • Prefer not to accept arbitrary URLs. When URL fetching is necessary, restrict destinations with a clear allowlist and enforce network-level egress controls.
  • Validate resolved IP addresses as well as hostnames, account for DNS changes, and validate every redirect—or disable redirects.
  • Treat cloud metadata endpoints as sensitive internal services, not as destinations that can be protected by a hostname block alone.
  • URL parsing helps understand a URL's components, but parsing or hostname validation by itself does not prevent SSRF.

What is an SSRF vulnerability?

SSRF is a vulnerability in which a server is tricked into making a request to an unintended destination. The application may accept a full URL, a hostname, or another value that it later uses to construct a request. The problem is not that URLs are inherently dangerous; it is that the server may be able to reach more systems than the person supplying the input.

A vulnerable feature might fetch a user-provided image URL to create a preview. If the application only checks that the value looks like a URL, it may also attempt to contact an internal service, a loopback address, or a cloud provider's metadata service. Depending on the environment and the application's response handling, the result could expose data, trigger an internal action, or cause an observable side effect.

SSRF can be direct, where the application returns fetched content to the user, or blind, where the request happens but the response is not shown. A lack of visible response data does not prove that a URL-fetching feature is safe.

A fictional lab scenario: an image preview service

Imagine a fictional application called PreviewBox. In an isolated training lab, it accepts an image URL and retrieves the image from the application server so it can display a preview. The intended destination is an approved public image host. The lab also contains a made-up internal service named records.lab.invalid, which is not a real public system and must not be contacted outside the lab.

If PreviewBox accepts any URL and fetches it without destination controls, a user may be able to make the application request destinations that the user cannot reach directly. The core security issue is the application's authority to make network requests on the user's behalf. The defensive lesson is to constrain that authority—not to try arbitrary destinations.

To understand how a URL is divided into a scheme, hostname, port, path, and other components, you can inspect URL components. A parser can help with analysis, but it does not determine whether a destination is safe to contact.

Why private IP restrictions are not enough

Blocking requests to private or local addresses is an important control, but a simple hostname check or a short list of blocked IPv4 addresses is not a complete SSRF defense. A server may have access to destinations represented in several ways, including IPv4 and IPv6 addresses, loopback and link-local ranges, internal DNS names, or addresses returned during DNS resolution.

A stronger policy starts with the destinations the feature actually needs. If the application only needs to fetch files from a small set of partner hosts, allow those exact destinations rather than trying to enumerate every unsafe destination. Where possible, also restrict the permitted scheme and port. For example, a feature intended for HTTPS downloads should not accept other schemes or arbitrary ports.

When an application resolves a hostname, validate the resulting IP addresses against the policy before connecting. Consider all returned address records, including IPv4 and IPv6 answers. Deny loopback, private, link-local, unspecified, multicast, and other non-public or otherwise prohibited ranges unless a documented use case explicitly requires them. Address-classification functions and special-purpose ranges can vary across libraries and versions, so do not treat a single helper or the label private as a complete policy.

An allowlist should compare complete, normalized hostnames—not string suffixes that can match unintended names. For example, a rule that accepts any hostname containing an approved domain as a substring is not equivalent to an exact-host allowlist. Internationalized names, trailing dots, unusual encodings, and parser differences are additional reasons to use well-maintained URL and networking libraries and to define normalization rules carefully.

DNS rebinding and connection-time checks

DNS rebinding can undermine a design that validates a hostname only once. A hostname might resolve to an allowed public address during validation and to a prohibited address when the HTTP client makes its connection. DNS answers may also include multiple addresses, and behavior can differ between the application's resolver and the networking library.

The security decision must apply to the address that is actually used for the connection. A robust design resolves the hostname, checks every candidate address against policy, and connects only to a vetted address. The HTTP client's handling of the original hostname, TLS certificate verification, and the Host header must remain correct; substituting an IP carelessly can break these checks or introduce new errors. A controlled outbound proxy or egress gateway can centralize destination and address enforcement, but it must itself be configured to apply the intended policy.

Do not rely on a hostname check followed by an unrelated, later DNS lookup. That creates a gap between what was validated and where the connection goes. Test the behavior of the actual HTTP client, resolver, proxy configuration, and runtime used by the application.

Redirect validation

A URL that passes validation can return a redirect to a different destination. If the HTTP client follows redirects automatically, it may make a second request that bypasses the checks applied to the original URL.

The simplest policy is to disable automatic redirects for user-controlled fetches. If redirects are needed, handle them explicitly: resolve each redirect target, apply the full URL and IP policy again, enforce a small redirect limit, and reject prohibited destinations. A relative redirect must be resolved against the current URL before it is checked. Do not assume that a redirect remains on the same host or uses the same scheme.

Cloud metadata and internal services

Cloud environments often provide metadata services so workloads can obtain information about their instance or configuration. Depending on the environment and workload permissions, metadata access may expose sensitive information, including credentials. Metadata services are commonly reachable through special network paths such as link-local addresses, so an application that can fetch arbitrary URLs may create a route to them.

Treat metadata endpoints and internal control-plane services as sensitive destinations. Block them at more than one layer where practical: application destination policy, outbound network rules, and cloud-specific workload or metadata protections. Do not rely only on blocking a metadata hostname; requests may use an address directly, a different name, or a redirect. Follow the cloud provider's current guidance for protecting metadata access and limiting the permissions of credentials available to workloads.

A safer URL-fetching design

The safest design is often to avoid fetching arbitrary user-supplied URLs. Consider whether the feature can instead accept an identifier for a known resource, use a fixed list of trusted sources, or let the user's browser retrieve public content directly when that meets the product's security and privacy needs.

If server-side fetching is required, use a layered workflow:

  1. Define the purpose. Specify which schemes, exact hostnames, ports, content types, and response sizes the feature needs.
  2. Parse once with a maintained library. Reject malformed URLs, unsupported schemes, unexpected credentials in the authority component, and disallowed ports. Parsing is input handling, not proof that a destination is safe.
  3. Apply a destination policy. Prefer exact host allowlists. Resolve hostnames and check every candidate address, including IPv4 and IPv6, against the policy.
  4. Connect only to a vetted destination. Ensure the actual connection uses an address that was checked, while preserving correct TLS hostname verification. Consider enforcing the same policy through a controlled egress proxy or network firewall.
  5. Control redirects. Disable them where possible; otherwise validate every new target before following it.
  6. Constrain the response. Set connection and total timeouts, cap response size, restrict accepted content types, and avoid returning raw internal error details to users.
  7. Limit impact. Run the fetching component with minimal network access and minimal credentials. Log policy rejections and unusual failures without logging secrets or unnecessarily storing full user URLs.

This workflow is a design checklist, not drop-in production code. The exact implementation depends on the HTTP client, DNS resolver, proxy arrangement, network topology, and cloud environment. Test those components together and keep their security behavior up to date.

Common mistakes and troubleshooting

  • Checking only the URL's text: A URL that looks public can resolve to an internal address. Check the address used for the connection as well.
  • Blocking only familiar IPv4 ranges: IPv6, link-local addresses, alternative representations, and environment-specific routes also matter. Use a defined address policy and verify it against the runtime's behavior.
  • Trusting DNS validation that happens earlier: A later DNS lookup may return a different address. Enforce policy at connection time or through a controlled network layer.
  • Validating only the first URL: Redirects can change the destination. Disable them or validate every hop.
  • Using a broad domain suffix rule: Partial string matches can allow unintended hostnames. Define exact, normalized allowlist entries.
  • Assuming a URL parser prevents SSRF: Parsing separates URL components; it does not control DNS, redirects, routing, or what the server can reach.
  • Treating a failed response as proof of safety: Blind requests may still reach a destination or cause an action. Review network logs and test controls in an authorized, isolated environment.

Defensive recommendations

Keep the feature's network permissions as narrow as its purpose allows. Prefer allowlists over denylist-only designs, enforce outbound restrictions outside the application as well as within it, and give the fetching process no unnecessary access to internal services or credentials. Keep redirects under explicit control, test DNS and IPv6 behavior, and monitor rejected requests and unexpected outbound traffic.

For security testing, use a fictional or isolated lab with systems you own or are explicitly authorized to assess. Never test SSRF payloads against real systems without authorization.

Conclusion

SSRF occurs when a server uses its network access to fetch a destination that a user can influence. Preventing it requires more than checking whether an input is a valid URL or blocking a few private IPs. Design around narrowly defined destinations, validate the addresses actually used, control redirects, protect cloud metadata, and reinforce application checks with network-level egress controls.

References