So this may (probably) just be that I'm not understanding XSRF prevention correctly, so feel free to tell me I'm an idiot. But currently in the code (https://github.com/angular/angular.js/blob/dd1d189ee785a37fe1d9bddf3818152db6aa210a/src/ng/http.js#L883-L893), angular is checking if the requested URL is same origin with urlIsSameOrigin(config.url). If it's not same origin, angular does not add the XSRF header token (X-XSRF-TOKEN).
Now, that's all good. Except that I'm requesting api.example.com from example.com, which fails the same origin check. Should this be allowed? Or does that somehow completely break the XSRF prevention?
Interesting. Since subdomains don't have access to cookies unless the cookie is specified with '.'-prefixed domain (.example.com) you would usually not have access to the authentication cookie (not xsrf cookie) at api.example.com unless it's shared across domains (in which case you don't have xsrf issue).
Now if you do use dot prefixed domain for auth cookie, and you use cookie based authentication for your api then you do need the xsrf token in the url to protect the app. that however means opting into the pre-flight requests for CORS, which complicates things quite a bit.
maybe a generic solution would be to provide a way to force XSRF token to be sent for CORS requests regardless of the same origin check. That way if for some reason you want to send XSRF token to your subdomain or totally unrelated domain and you are ready to deal with preflight CORS requests you have an option to do that.
@chirayuk what's your take?
api.example.com is not the same origin as example.com, and the spec makes no mention of "trusted origins". Unless I've horribly misunderstood CORS, a request to api.example.com from example.com would still incur CORS checks, including preflight.
@IgorMinar a flag to override the same origin check for XSRF tokens would indeed be nice.
Correct me if I'm wrong, but here's how I understand things:
An app in running on example.com and makes an HTTP request to api.example.com.
Angular has access to the XSRF token (set via a cookie on a domain that includes example.com) and needs to decide whether to add that to the headers of the HTTP request or not.
The XSRF token can be used by the server on example.com to verify that the request is coming from the actual app (and not from another malicious app running on the user's computer). If any malicious person controlling a domain other than example.com, could get a hold of our XSRF token, then they could easily trick the user into sending arbitrary requests to example.com, which example.com could not distinguish from legitimate requests made through the app that it is serving.
So, the moment we start sending XSRF tokens to any domain othar than the one we are currently running from, we are in the mercy of anyone controlling that domain. Taking that into account, allowing people to disable the "same origin" check, sounds like a really bad idea - you could as well drop XSRF altogether.
There is obviously no problem if the same person controls both example.com and api.example.com, so one might consider adding a flag for sending the XSRF token to subdomains of the current domain. I don't think it is a good idea in general, since there are several cases where a domain and a subdomain are not under the same person's control (e.g. shared hosting).
A better option might be allowing users to whitelist specific domains for sending the XSRF token or allowing people to specify that subdomains should also receive the XSRF token and leave it up to them to make sure that their app will always be deployed on domains, where they have full control over subdomains.
Thoughts?
the white-list option sounds the best to me.
Well this is old... +1 for whitelisting. I guess that's what I meant by "trusted" domains.
Yep. Checking for same origin is very strange behavior, imho.
I use domain.zone and api.domain.zone in my app and set cookies *.domian.zone.
So I can read cookie XSRF-TOKEN in app only loaded from this domains. So its OK for me, but there is urlIsSameOrigin() check and angular fails inserting x-xsrf-token header.
The only way - to use custom $http interceptor.
There is a PR (#14890) for making this configurable, but it hasn't gotten much traction (yet) :grin:
@gkalpak is there a way of doing this in the current implementation of Angular? This is the exact issue I'm having. HttpXsrfTokenExtractor.getToken() always returns null because my rest api that is providing the cookie is cross-origin.
No idea :grin:
Maybe you could ask on https://gitter.im/angular/angular or StackOverflow.
Most helpful comment
Correct me if I'm wrong, but here's how I understand things:
An app in running on
example.comand makes an HTTP request toapi.example.com.Angular has access to the XSRF token (set via a cookie on a domain that includes
example.com) and needs to decide whether to add that to the headers of the HTTP request or not.The XSRF token can be used by the server on
example.comto verify that the request is coming from the actual app (and not from another malicious app running on the user's computer). If any malicious person controlling a domain other thanexample.com, could get a hold of our XSRF token, then they could easily trick the user into sending arbitrary requests toexample.com, whichexample.comcould not distinguish from legitimate requests made through the app that it is serving.So, the moment we start sending XSRF tokens to any domain othar than the one we are currently running from, we are in the mercy of anyone controlling that domain. Taking that into account, allowing people to disable the "same origin" check, sounds like a really bad idea - you could as well drop XSRF altogether.
There is obviously no problem if the same person controls both
example.comandapi.example.com, so one might consider adding a flag for sending the XSRF token to subdomains of the current domain. I don't think it is a good idea in general, since there are several cases where a domain and a subdomain are not under the same person's control (e.g. shared hosting).A better option might be allowing users to whitelist specific domains for sending the XSRF token or allowing people to specify that subdomains should also receive the XSRF token and leave it up to them to make sure that their app will always be deployed on domains, where they have full control over subdomains.
Thoughts?