Are preflight requests made for ajax call to same origin domain? - ajax

This answer states, that one way X-Requested-With header prevents CSRF attacks is that if server doesn't allow it then a modern browser wont allow javascript code to add this header. And if header is present server can be sure that request didn't originate from another page a user might have opened.
To my understanding the way browser determines whether a custom header is allowed or not in an ajax request is by making a preflight request. And then a server responds with header Access-Control-Allow-Headers. Which contains list of headers allowed for a request in question. So if servers returns an empty list then CORS ajax calls couldn't have xhr header present. Indicating different origin.
So my question is whether preflight request is triggered if origin is the same. Because if they are, then server would say dont add any header, and if browser doesn't then to server a request from its own origin would be indistinguishable from another origin.

So my question is whether preflight request is triggered if origin is the same.
No, it isn't.
Because if they are, then server would say dont add any header, and if browser doesn't then to server a request from its own origin would be indistinguishable from another origin.
The browser not sending a preflight request doesn't stop the server from testing the actual request for a header and throwing an error if it isn't present.

Related

What does "Response to preflight request doesn't pass access control check" mean?

I have receive the following response when trying to access an API via an ajax request in Chrome:
"Failed to load http://localhost:1880/api_resource: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:3000 is therefore not allowed access."
As you can see from the message, both client and API are running locally.
I understand that this situation relates to a CORS cross origin request. I see that there are similar questions about this on stack overflow, but from those answers I do not understand what the message is telling me and where it comes from.
Specifically I understand that the response header "Access-Control-Allow-Origin" must be set (typically to '*') to allow access to the API from a different domain to the one on which the API is being served. But the message seems to relate to the request and not the response, and as far as I am aware, no request ever reaches the API.
What is a preflight request and how is it failing?
As I now understand it, modern browsers will issue a 'preflight' request before the actual cross origin request. This preflight request uses the 'OPTIONS' HTTP verb along with the CORS headers Access-Control-Request-Method and Access-Control-Request-Headers to which it expects to see a response with valid Access-Control-Allow-Origin in the header that indicates that the server understands the CORS protocol and will allow the actual (GET/POST/PUT) request.
The message "Response to preflight request doesn't pass access control check" means that the browser did not see a valid "Access-Control-Allow-Origin" header in the Options response.
In my case this was because the server (implementing a REST API) was set up to respond correctly to PUT and POST requests but not setup to respond to OPTIONS requests with the CORS headers.
in my case the problem was for my website address, i'm calling all apis from the same server but i got this error.
my website address is sateh.ir
so im my ajax request i set the url: http://sateh.ir/api/...
after getting this error and working on it for some hours, i got that i had to set ajax url to: http://www.sateh.ir/api/...
i dont know why my website cant understand that i'm calling api from the same server if i dont put 'www', but that was my problem at all.

Handling CORS for API that serving ajax call and server to server calls

I'm building an endpoint (let say /v1/getdata). This endpoint will serve a call from both ajax and server to server. Since this endpoint has different origin than the website that will use it (lets say http://www.t.com), i need to implement a CORS for ajax call. I know i must add Access-Control-Allow-Origin: * header to response whenever the request has http://www.t.com in it's Origin header, so the browser will accept ajax call from cross origin.
But server to server call doesn't send Origin header. What is the best approach for this? Should i add Origin header manually into the request from server?
If you are making the API public, then you can simply add Access-Control-Allow-Origin: * to all responses.
If you are making it available to only certain sites, then the logic you should use is:
Is the Origin request header present?
If not, don't add an Access-Control-Allow-Origin response header
Is the Origin one that is on your whitelist of acceptable sites?
If not, don't add an Access-Control-Allow-Origin response header
Otherwise, add an Access-Control-Allow-Origin response header
with a value that matches the Origin request header

Cookie in AJAX response from other domain not honored - are there workarounds

I have a server-side API on the domain api.example.com
User is visiting www.website.com where a script makes an XmlHttpRequest to api.example.com and gets a response with a cookie.
It appears the API's response cookie is not honored by the HTTP agent.
I'm aware of the non-cross-domain-leaking-cookie policy, but I thought the domain here would be api.example.com. Seems I guessed wrong.
Is there some other way that my API on api.example.com could remember user data from one site to another? If not, how could services like Criteo and other retargeting sites work, from this point of view?
Make sure your API set:
Access-Control-Allow-Credentials header to true in possible preflight response and regular response,
Access-Control-Allow-Origin header to value of the origin from the actual request,
and client sets XMLHttpRequest.withCredentials to true.

CORS-aided cross-origin-XHR

Modern browsers support CORS handily. If CORS-aided cross-origin-XHR is sent to CORS-ignorant site, the XHR succeeds in no question.
Does it expose more vulnerability in this regard? How to strictly enforce Same Origin Policy on today's browsers?
Take a look at how preflight requests work in CORS. The CORS preflight request protects servers from unauthorized requests by first asking the server whether it is ok to make the cross-origin request. If the server says "yes", the browser continues with the request. Otherwise the request fails.
Note that there are certain types of requests that don't need preflight requests. However, these requests were already possible even before CORS. For example, a simple GET request does not need a preflight, but a GET can already be made with a script tag.
You can learn more about CORS and the preflight here: http://www.html5rocks.com/en/tutorials/cors/

Send credentials in preflighted request (CORS)

I have to make CORS with content type JSON. This makes the browser send first an OPTIONS request, specifying origin and so on. Then the server should answer with allowed domains, methods, etc. If this goes well, the browser sends the actual request.
My problem is that the server needs authentication for the actual request but ALSO for the OPTIONS request. But the browser doesn't send the authentication headers with the OPTIONS request.
I'm using JQuery and the ajax() function. I tried adding "withCredentials: true", and add the Authorization header, but this not affect the OPTIONS request, it still doesn't send any credentials.
Any ideas? Thanks in advance.
The preflight request is only meant to verify if the CORS request itself is allowed. Therefore, cookies are never included in the preflight request. You'd have to validate the user during the actual request.
Actually, Chrome will send the cookies w/ the preflight request if withCredentials=true whereas Firefox will not. Sounds like they've implemented the spec differently.

Resources