After reading a lot about CORS and pre-flight requests I still don't quite get why there are some exceptions for doing a pre-flight. Why does it matter if the Content-Type is 'text/plain' or 'application/json'?
If I get it right, the value of CORS is to restrict the returned data (It doesn't care if the POST destroyed the database, it only cares that the browser can't read the output of that operation). But if that's true (and probably It's not) why there are pre-flight requests at all? Wouldn't suffice to just check for a header like 'Access-Control-Allow-Cross-Origin-Request: true' in the response?
The best answer so far I found in the: CORS - What is the motivation behind introducing preflight requests? question, but it's still a bit confusing for me.
Why does it matter if the Content-Type is 'text/plain' or 'application/json'?
The three content types (enctype
) supported by a form are as follows:
application/x-www-form-urlencoded
multipart/form-data
text/plain
If a form is received by a handler on the web server, and it is not one of the above content types then it can be assumed that it was an AJAX request that sent the form, and not an HTML <form />
tag.
Therefore, if an existing pre-CORS system is using the content type as a method of ensuring that the request is not cross-site in order to prevent Cross-Site Request Forgery (CSRF), then the authors of the CORS spec did not want to introduce any new security vulnerabilities into existing websites. They did this by insisting such requests initiate a preflight to ensure both the browser and the server are CORS compatible first.
It doesn't care if the POST destroyed the database, it only cares that the browser can't read the output of that operation
Exactly right. By default browsers obey the Same Origin Policy. CORS relaxes this restriction, allowing another Origin to read responses from it made by AJAX.
why there are pre-flight requests at all?
As said, to ensure that both client and server are CORS compatible and it is not just an HTML form being sent that has always been able to be submitted cross domain.
e.g. this has always worked. A form on example.com
POSTing to example.org
:
<form method="post" action="//example.org/handler.php" />
Wouldn't suffice to just check for a header like 'Access-Control-Allow-Cross-Origin-Request: true' in the response?
Because of the CSRF vector. By checking that the browser can send a preflight, it ensures that the cross-origin request is authorised before the browser will send it (by examining CORS response headers). This enables the browser to protect the current user's session - remember that the attacker here is not the one running the browser, the victim is running the browser in a CSRF attack, therefore a manipulated browser that doesn't properly check CORS headers or spoofs a preflight would be of no advantage for an attacker to run themselves. Similarly, the preflight enables CSRF mitigations such as custom headers to work.
To summerise:
enctype
's<form>
submission will be standard (or "simple" as CORS puts it)enctype
'senctype
's in fully supported browsers
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With