DEV Community

Serguey Asael Shinder
Serguey Asael Shinder

Posted on

Your Server Will Fetch Any URL You Give It

Somewhere in your product
there is a field where a user types an address,
and your server goes and fetches it.

Import from a link.

An avatar from a URL.

A webhook you promise to call.

A preview card.

A document that pulls in images.

It looks like the user's request.

It is not.

It is your server's request,
made from inside your network,
with everything your server can reach.

That is the whole vulnerability,
and it needs no clever payload at all.

Your server can reach things
the internet cannot.

The admin interface on localhost.

The metadata service
that hands out cloud credentials
to whatever asks nicely.

Staging.

The internal dashboard
that has no login
because it is internal.

A stranger with a text box
cannot touch any of that.

Your server can,
and you have built them
a polite way to ask.

The first fix everyone writes
is a blocklist,
and a blocklist does not hold.

A hostname can resolve
to an internal address.

A redirect can make
an innocent first hop
land somewhere else on the second.

A name can pass your check
and resolve differently
by the time the socket opens.

There are more ways to write
an address than you will think of
on a Tuesday afternoon.

Do it the other way round.

Allow the hosts you meant to allow,
if you can name them,
because almost always
there are four.

If you cannot name them,
resolve it yourself,
inspect the address you got back,
and connect to that address,
not to the name a second time.

Follow no redirects,
or check every hop the same way.

Then take away the reach.

Make those calls from something
with no route to anything internal.

A separate egress.
A proxy that only speaks outward.

Then a check that fails
is not the end of the story.

Cap the size.

Cap the time.

Do not hand the raw response
back to the person who asked for it.

Anything your server can reach,
a stranger can reach through it.

Draw that map yourself,
before somebody else does.

– Serguey Asael Shinder

Top comments (0)