Rob--W / cors-anywhere

CORS Anywhere is a NodeJS reverse proxy which adds CORS headers to the proxied request.
MIT License
8.69k stars 6.13k forks source link

Alternative "Origin" header to bypass forbidden requirement #212

Closed src-r-r closed 4 years ago

src-r-r commented 4 years ago

I'm attempting to use client-side code to fetch remote resources (e.g. https://ron-swanson-quotes.herokuapp.com/v2/quotes). As an example...

axios({
    method: 'get',
    url: "http://localhost:8080/https://github.com/Rob--W.atom",
  })
  .then((response) => {
    console.log(`Fetching ${url}: ${JSON.stringify(response)}`);
  })
  .catch((err) => {
    console.error(err.status)
    console.error(`Fetching ${url} : \n${err["message"]}`);
    console.error(err);
  });

This is an interesting scenario. Because the remote server treats the request as a CORS request, so it (usually) denies the request (unless the server is set to wide-open CORS!)

That's where cors-anywhere is supposed to help. However, since the request is made in the client the Origin header is not set and we get the following error:

Missing required request header. Must specify one of: origin,x-requested-with

So, set the Origin header right? Unfortunately, most browsers disallow this. This might work for server-side code, but this doesn't work for client-side.

I have a working solution (which I'll link to) where we use a "fake" header (like x-cors-origin that is then substituted in for Origin. I tested it in postman:

GET http://localhost:8080/https://github.com/Rob--W.atom
HEADERS:
  "x-cors-origin": "https://github.com/Rob--W.atom"

RESPONSE:
  <?xml version="1.0" encoding="UTF-8"?>
    <feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
    <id>tag:github.com,2008:/Rob--W</id>
    <!-- .... -->
src-r-r commented 4 years ago

Here's my given solution: https://github.com/src-r-r/cors-anywhere

Would you like me to submit a pull request?

Rob--W commented 4 years ago

The Origin header is intentionally not spoofable for requests from web browsers. That's why it is used to authenticate the client. When you add a custom header, then anyone can spoof this value, which makes it rather unfitting for verifying the origin.

The only remaining use of the custom header is to check that it is present (to distinguish it from direct requests, i.e. visiting the page in a web browser). For that, I have already added the X-Requested-With header, as you can see from the error message.

Missing required request header. Must specify one of: origin,x-requested-with

prusswan commented 3 weeks ago

Just spoofing the origin header may be insufficient as some endpoints deny additional headers (triggering preflight requests that cannot be spoofed). What might work would be some means for the cors proxy to proxy specific endpoints according to some predefined swop list, without the use of custom headers.