Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Adding XSRF header when request is NOT same origin, but is TRUSTED origin (subdomain) #7862

Closed
brettstack opened this issue Jun 17, 2014 · 9 comments

Comments

@brettstack
Copy link

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 (

angular.js/src/ng/http.js

Lines 883 to 893 in dd1d189

if (isUndefined(cachedResp)) {
var xsrfValue = urlIsSameOrigin(config.url)
? $browser.cookies()[config.xsrfCookieName || defaults.xsrfCookieName]
: undefined;
if (xsrfValue) {
reqHeaders[(config.xsrfHeaderName || defaults.xsrfHeaderName)] = xsrfValue;
}
$httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout,
config.withCredentials, config.responseType);
}
), 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?

@IgorMinar IgorMinar self-assigned this Jul 25, 2014
@IgorMinar
Copy link
Contributor

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?

@IgorMinar IgorMinar added this to the Purgatory milestone Jul 25, 2014
@lord2800
Copy link

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.

@btford btford removed the gh: issue label Aug 20, 2014
@gkalpak
Copy link
Member

gkalpak commented Jun 7, 2016

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?

@IgorMinar
Copy link
Contributor

the white-list option sounds the best to me.

@brettstack
Copy link
Author

Well this is old... +1 for whitelisting. I guess that's what I meant by "trusted" domains.

gkalpak added a commit to gkalpak/angular.js that referenced this issue Jul 10, 2016
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origin, so that requests to these origins
will include the XSRF token.

Fixes angular#7862
gkalpak added a commit to gkalpak/angular.js that referenced this issue Jul 10, 2016
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
gkalpak added a commit to gkalpak/angular.js that referenced this issue Aug 8, 2016
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
@kityan
Copy link

kityan commented Mar 2, 2018

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.

@gkalpak
Copy link
Member

gkalpak commented Mar 2, 2018

There is a PR (#14890) for making this configurable, but it hasn't gotten much traction (yet) 😁

gkalpak added a commit to gkalpak/angular.js that referenced this issue Mar 16, 2018
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
gkalpak added a commit to gkalpak/angular.js that referenced this issue Mar 16, 2018
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
gkalpak added a commit to gkalpak/angular.js that referenced this issue Mar 21, 2018
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
gkalpak added a commit to gkalpak/angular.js that referenced this issue Mar 26, 2018
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes angular#7862
@RothAndrew
Copy link

@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.

@gkalpak
Copy link
Member

gkalpak commented Mar 28, 2018

No idea 😁
Maybe you could ask on https://gitter.im/angular/angular or StackOverflow.

@gkalpak gkalpak closed this as completed in 1e90d03 Apr 4, 2018
gkalpak added a commit that referenced this issue Apr 5, 2018
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes #7862
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.