Skip to content
routebase
API Security12 chapters

Chapter 05 of 12

Server Side Request Forgery

API7:2023 turns any URL field in a request body into an instruction your server carries out, which is why the defence is an allow list rather than a filter.

Most of this guide is about requests your API answers. This chapter is about requests your API makes, because a field that holds a URL is an instruction that somebody else wrote.

OWASP lists it as API7:2023 Server Side Request Forgery, and its reference is CWE-918.

Why your server is the attractive proxy

The caller is outside and your service is inside. It resolves internal names, and it reaches addresses that are not routable from the internet. In a cloud environment it can often reach an instance metadata service that hands out credentials to whatever asks from the right place.

A feature that fetches a URL on behalf of a caller lends all of that out. The attacker supplies a destination, your server makes the request with its own position and its own privileges, and the interesting part is whatever comes back.

Blind variants still work. Even when the response body never reaches the caller, timing and status differences leak whether a host answered. That is enough to map an internal network patiently, so treat "we do not return the response" as useful hardening rather than as a fix.

The fields nobody thinks of as URL fields

Webhook and callback destinations are the obvious case, and they are the case teams already guard.

The quieter ones are everywhere. They include an avatar URL on a profile update, an import-from-URL field, a renderer pointed at a page and a link preview. Anything that resolves a document reference or takes a file by location rather than by upload belongs on the same list. Each of them ends with your server making a request to a destination a caller chose.

The question to ask about each field is not what it is called. It is whether anything in the system ever fetches it.

Allow list, and the four other controls

OWASP's guidance for this category is unusually specific, and the parts worth carrying into an API are these.

Keep an allow list of destinations, schemes and ports. The feature exists to reach a known set of origins, so name them. This is the control that survives creativity, because it does not depend on predicting how an attacker will spell an internal address.

Do not follow redirects. A destination that passed your check can answer with a redirect to one that would not have. Disabling redirection on the fetching client removes the whole class.

Use a maintained URL parser. Parsing differences between the component that validates and the component that fetches are a standing source of bypasses, so let one well-tested library do both.

Separate the fetcher from the internal network. A resource fetching function that runs where it cannot reach internal services has a much smaller blast radius when a check is wrong.

Do not return the raw response. Serve what the feature needs, such as a stored image or a parsed field, rather than handing back whatever the destination said.

In Routebase

api7-ssrf reads request body schemas rather than guessing at fields. It inspects POST and PUT bodies for URL-shaped property names, including url, uri, callback, webhook, redirect, target, endpoint, imageUrl and src, which is one of the places where having a specification pays for itself.

It then decides on two signals. A response that echoes markers from a well-known internal destination raises a Critical finding, because that is direct evidence the fetch happened and the content came back. A successful response that takes longer than five seconds raises a Medium finding at low confidence, since an outbound call is one explanation for the delay and ordinary network latency is another.

The usual false positives follow from that design. A URL field validated server-side looks the same from outside as one that is not, and a field the server only stores and displays is never fetched at all. Both are worth marking as such with a note, which the triage chapter covers.

Because the scanner works from the request body schema, a schema that documents its URL fields properly gets a better scan than one that types them all as free-form strings. See Schemas for the modelling side and the Scanner Reference for the probe behaviour.

Frequently asked questions

What is server side request forgery in an API?

It is a feature that fetches a URL supplied by the caller, used to reach something the caller could not reach directly. Your server sits inside the network and has credentials the caller does not, so it makes a very effective proxy. OWASP lists it as API7:2023 and its reference is CWE-918.

Which API fields cause SSRF?

Any field whose value becomes a request your server makes. Webhook and callback URLs are the obvious ones, and the quieter ones are avatar or image URLs, import-from-URL fields, PDF and screenshot renderers, link previews and anything that resolves a document reference. The risk comes from the fetch rather than from the field name.

Why is a blocklist not enough to stop SSRF?

Because a blocklist has to anticipate every spelling of a destination, and the address space offers many. Decimal and hexadecimal forms of an address, redirects to an internal host, DNS names that resolve inward and alternative schemes all get past a naive filter. An allow list of the destinations the feature actually needs does not have that problem.

How do you test an API for SSRF safely?

Check the behaviour rather than the exploit. For each URL field, ask whether the value is ever fetched, whether the destination is checked against an allow list, whether redirects are followed and whether the response body reaches the caller. Those four answers tell you the exposure without pointing a payload at anything.

Last reviewed by The Routebase Team.

Ready to ship on it?

Routebase is live. Design your API once — docs, mocks, tests, and monitoring all follow from the same source.

14-day Pro trial — no credit card required.