Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no preflight in CORS for POST requests with standard content-type

I'm a bit confused about the security aspects of CORS POST requests. I know there is a lost of information about this topic online, but I couldn't find a definite answer to my questions.

If I understood it correctly, the goal of the same-origin policy is to prevent CSRF attacks and the goal of CORS is to enable resource sharing if (and only if) the server agrees to share its data with applications hosted on other sites (origins).

HTTP specifies that POST requests are not 'safe', i.e. they might change the state of the server, e.g. by adding a new comment. When initiating a CORS request with the HTTP method POST, the browser only performs a 'safe' preflight request if the content-type of the request is non-standard (or if there are non-standard http headers). So POST requests with standard content-type and standard headers are executed and might have negative side effects on the server (although the response might not be accessible to the requesting script.)

There is this technique of adding a random token to every form, which the server then requires to be part of every non-'safe' request. If a script tries to forge a request, it either

  1. does not have the random token and the server declines the request, or
  2. it tries to access the form where the random token is defined. This response with the random token should have the appropriate head fields, such that the browser does not grant the evil script access to this response. Also in this case the attempt fails.

My conclusion is that the only protection against forged POST requests with standard content-type and headers is the technique described above (or a similar one). For any other non-'safe' request such as PUT or DELETE, or a POST with json-content, it is not necesssay to use the technique because CORS performs a 'safe' OPTIONS request.

Why did the authors of CORS exclude these POST exempt from preflight requests and therefore made it necessary to employ the technique described above?

like image 305
sauerburger Avatar asked Sep 27 '16 13:09

sauerburger


People also ask

What triggers a CORS preflight?

A CORS preflight OPTIONS request can be triggered just by adding a Content-Type header to a request — if the value's anything except application/x-www-form-urlencoded , text/plain , or multipart/form-data .

Under what circumstances is a request preflight?

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method , Access-Control-Request-Headers , and the Origin header.


1 Answers

See What is the motivation behind the introduction of preflight CORS requests?.

The reason CORS doesn’t require browsers to do a preflight for application/x-www-form-urlencoded, multipart/form-data, or text/plain content types is that if it did, that’d make CORS more restrictive than what browsers have already always allowed (and it’s not the intent of CORS to put new restrictions on what was already possible without CORS).

That is, with CORS, POST requests that you could do previously cross-origin are not preflighted—because browsers already allowed them before CORS existed, and servers knew about them. So CORS changes nothing about those “old” types of requests.

But prior to CORS, browsers wouldn’t allow you to do a cross-origin application/json POST at all, and so servers could assume they wouldn’t receive them. That’s why a CORS preflight is required for those types of “new” requests and not for the “old” ones—to give a heads-up to the server: this is a different “new” type of request that they must explicitly opt-in to supporting.

like image 166
sideshowbarker Avatar answered Sep 18 '22 07:09

sideshowbarker