DEV Community

Serguey Asael Shinder
Serguey Asael Shinder

Posted on

Your API Lets Any Website Read It With Your Users' Cookies

The front end moved
to its own subdomain,
and the browser started refusing
to let it read the API.

Somebody searched the error,
found the header,
and made the error go away.

Read the Origin of the request.
Write it back
as the allowed origin.
Allow credentials.

It worked first time.

It also works
for every other website on earth.

Here is what that header says.

When a page somewhere else
asks the browser
to call your API,
the browser sends your user's cookies along,
because they are your cookies
and that is what cookies do.

Then the browser asks your server
whether that page is allowed
to read the answer.

Your server says yes.

It says yes to everyone,
because it repeats back
whatever name it was given.

So a stranger's page,
opened in a tab
by somebody who is logged in to you,
can quietly call your account endpoint
and read the name,
the address,
the order history,
and the token you kindly put
in the response body.

No password stolen.
No session hijacked.

Your own server
signed the permission slip.

The other common version
is the clever one.

Allow any origin that ends
with your domain name.

Which is also true
of a domain somebody registers
with your name glued on the front.

And allowing null
lets in sandboxed frames
and local files,
which is a door nobody meant to open.

The fix is a list.

Exact origins.
Scheme, host and port,
written out in full,
in config you can review.

Compare against the list
as whole strings.
No suffix matching.
No patterns.
No echo.

If an origin is not on the list,
send no CORS header at all
and let the browser do its job.

Then ask whether the endpoint
needs credentials at all.

A public catalogue does not.
Make it public,
without cookies,
and keep credentialed access
for the handful of origins
that are actually yours.

CORS is not a lock on your API.

It is a list of who may read
over your user's shoulder.

Write the list by hand.

– Serguey Asael Shinder

Top comments (0)