4

I've been working on a classic SPA where the front end app lives on app.example.com while the API lives on api.example.com, hence requiring the use of CORS requests. Have setup the server to return the CORS header, works fine.

Whenever an AJAX request is not simple, the browser makes an extra OPTIONS request to the server to determine if it can make the call with the payload. Find Simple Requests on MDN

The question is: What are the actual benefits of doing the OPTIONS request, especially in regards to security?

Some users of my app have significant geographical latency and since the preflight cache doesn't last long, the preflight requests cause latencies to be multiplied.

I'm hoping to make POST requests simple, but just embedding the Content-Type of application/json negates that. One potential solution is to "hack" it by using text/plain or encoding in the url. Hence, I hope to leave with a full understanding of what CORS preflight requests do for web security. Thanks.

Damon Aw
  • 4,603
  • 3
  • 26
  • 37

1 Answers1

2

As noted on the article you linked to:

These are the same kinds of cross-site requests that web content can already issue, and no response data is released to the requester unless the server sends an appropriate header. Therefore, sites that prevent cross-site request forgery have nothing new to fear from HTTP access control.

Basically it was done to make sure CORS does not introduce any extra means for cross-domain requests to be made that would otherwise be blocked without CORS.

For example, without CORS, the following form content types could only be done cross-domain via an actual <form> tag, and not by an AJAX request:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

Therefore any server receiving a request with one of the above content-types knows that there is a possibility of it coming from another domain and knows to take measures against attacks such as Cross Site Request Forgery. Other content types such as application/json could previously only be made from the same domain, therefore no extra protection was necessary.

Similarly requests with extra headers (e.g. X-Requested-With) would have previously been similarly protected as they could have only come from the same domain (a <form> tag cannot add extra headers, which was the only way previously to do a cross-domain POST). GET and POST are also the only methods supported by a form. HEAD is also listed here as it performs identically to GET, but without the message body being retrieved.

So, in a nutshell it will stop a "non simple" request from being made in the first place, without OPTIONS being invoked to ensure that both client and server are talking the CORS language. Remember that the Same Origin Policy only prevents reads from different origins, so the preflight mechanism is still needed to prevent writes from taking place - i.e. unsafe methods from being executed in a CSRF scenario.

You might be able to increase performance using the Access-Control-Max-Age header. Details here.

Community
  • 1
  • 1
SilverlightFox
  • 28,804
  • 10
  • 63
  • 132
  • Similarly, if you had a bad browser that allowed cross domain requests without CORS protection and you didn't do CSRF, you are equally vulnerable? The key is that you should have the adequate protection in place for simple requests **already**, if you didn't, having preflight requests for simple requests won't help. For non simple requests, having preflight requests is kind of a "protection by awareness". If the server fails to respond to `OPTIONS`, the browser won't continue anyway, so not to change things for legacy servers. – Damon Aw Feb 18 '16 at 07:15
  • The point above is my own reasoning after reading this [answer](http://stackoverflow.com/questions/15381105/cors-what-is-the-motivation-behind-introducing-preflight-requests). If you agree, how about wording some extra bits on it and linking to the question? Will make the answer complete for future readers :) – Damon Aw Feb 18 '16 at 07:18