Problems with per-user subdomain sessions & Google OAuth2 - oauth

We're developing an application that hosts each user account under their own subdomain. Separate users may access their application through a domain such as usera.myapp.com and userb.myapp.com.
To enhance security between application accounts, the session cookies are scoped to the subdomain of the account (ex. usera.myapp.com instead of .myapp.com). This seems to pose a problem with Google's OAuth2 implementation. Since Google OAuth will only allow you redirect back to the set redirect_uri in their settings, we cannot redirect the user back to their custom subdomain after authorizing our app. We're forced to redirect them back a single generic subdomain such as oauth.myapp.com.
Once they're redirected, we no longer have access to the session (sessions are scoped to a different subdomain now). Since we no longer have access to the session, we cannot check the CSRF token we set to the "state" parameter when requesting the OAuth token. Most other implementations of OAuth2 will allow us to redirect back to a wildcard subdomain, so this isn't an issue.
Now we are left with 2 possible solutions to fix this issue...
Skip checking the CSRF token in the "state" parameter, which opens us up to clikjacking attacks. Or...
Open up our session cookies to use the entire domain, instead of scoping them to the the account subdomain. This opens it's own can of worms and security issues, but it is something that we can deal with.
Option #2 seems like the lesser of the two evils, but I'd like some input before we proceed with doing that.
Thoughts?

Hm, might it be possible to construct the state value by hashing up a bunch of pieces of state so you don't have to retrieve the desired value from a cookie? E.g. hash up the subdomain, the time of day, and some internal system state from your app. Then you can recompute the value you expect when they show up at oauth.myapp.com, no need to fetch it from the session. Should be effective against clickjacking I’d think.

Related

Linkedin OAuth2.0 : How to configure OAuth 2.0 Redirect URL with a wildcard subdomain url for a multi tenant application

I am trying to configure a LinkedIn application for a multi tenant site. I will have 20+ tenants using the same application and the number is going to increase every time.
As per Linkedin API documentation (https://developer.linkedin.com/docs/oauth2) we need to ensure following points
We strongly recommend using HTTPS whenever possible
URLs must be
absolute (e.g. "https://example.com/auth/callback", not
"/auth/callback")
URL arguments are ignored (i.e.
https://example.com/?id=1 is the same as https://example.com/)
URLs
cannot include #'s (i.e.
"https://example.com/auth/callback#linkedin" is invalid)
Can i configure redirect url as https://*.mysite.com/auth/linkedin/callback instead of specifying url of each tenant separately.
You cannot do a subdomain based wild card mapping as the IP should know the RP.
You can change the logic after you get the authorization callback, so you set the cookie and then you will have to redirect the user back to the tenant URL instead of the base URL.
Anyway, after successful authorization, you will be redirecting the user to an action, just figure out the subdomaina and the construct the URL and do the redirection
HTH
EDIT
Since the use of the URL or other approaches seem to be a hack, can you please try to have a facade like application (or Gateway like one) that has a URL that is registered in linkedin and then on receiving the response, it can use a state or other factor to redirect to the tenant URL. This can use a 302 and it will be invisible unless the user is on a very slow network. This approach does not require any hack like approach.
Here state can be a function that takes a tenant info and generates a dynamic hash that is stored for tracking and redirection.

Rails: one app with 2 domains - share authentication

My site is at mydomain.com on Heroku with Devise authentication.
I bought a short url me.do that I also point to my same Heroku app.
When a user is signed in on mydomain.com I also need them to be signed in on me.do so when they go to me.do after signing in at mydomain.com they don't have to sign in again.
How can I share authentication sessions using Devise on both mydomain.com and me.do?
There is no easy way to share authentication across domains, since the authentication usually is bound to cookies (sessions) which only bind to one domain and are not accessible across domains.
The only way you can manage to have something like this is to make sure you set cookies on both domains on login. You can do this via a redirect loop:
login request arrives at domain1 (from login form for example)
you set the session cookie for domain1
then make a redirect to domain2 and set a session cookie there
and then redirect the user back to domain1 (proceeding where he originally was going)
to make sure this is not an endless loop you have to add some parameters in the redirects to know how to handle the situation.
BUT if at all possible to avoid it, i would advise you not to implement this. It is really bad practice to have not unique domains. even allowing domains with www and without can lead to quite a bit of confusion for the user and a lot of headaches to the developer - in your case it will be even worse.
The sessions are not as useful as they would normally be. Setting additional cookies or session values does NOT work anymore (unless you do the loop every time again). And until the user actually uses the second domain his session there might even have expired (depending how your authentication framework handles it).
Those are just some of the issues you might run into.

How to authenticate from a token in a URL?

I need to create a website with non standard authorizaion logic (or rather not exactly the site. It should be separate Area in existing ASP.NET MVC3 application). Access to most of the pages sould be available only to authorized users. Authorization is carried out on the token passed in the link. After the user arrived to this area, the token should be checked and if it’s valid site will create a session key for 30 minutes (we already have our own mechanisms of session managment and it should be used).
Workflow example :
Third-party website generates a link for user, e.g. https://example.com/securedPage/?accountId=123456&token=XXXXX
Our site check this token (it depends on the page from URL, in this case https://example.com/securedPage/)
If the token is valid, example.com obtains a session key for the user and stores it in cookies.
Then user continues browsing whole website and only session is checked.
I’m new to MVC framework, so I’d like to ask several questions about architecture.
What is an apropriate place for this logic? ActionInvoker, Global.asax etc.?
Currently I'm trying to create my own ActionInvoker and keep this logic there, but I'm afraid that it could be a wrong way.
If I understand correctly you want yo extend the Action of the controller to inject/check your token.
I think the global action filters should help you.

Copying cookies from main domain to subdomain

My application has a userspace which used to be accessed by a url like domain.com/~username, but I am in the process of converting that to using subdomains instead (username.domain.com). However, I am running into an issue that I'm hoping someone might have an idea of how to get around.
Currently, visitors to a user's site get a cookie of the form user<id>_authentication (where <id> is the user ID of the site they're visiting), which is set to have the domain www.domain.com. However, now that I'm switching to subdomains, I want to find those cookies and transfer them to a new cookie called authentication per subdomain, using the subdomain as the cookie domain. However, the rails cookies array does not find the main domain cookies.
I know that if the old cookies were using .domain.com as the domain instead, they'd apply to the subdomain and would be present in cookies, but these cookies are already existing, and I'm trying to make the change as seamless for a user as possible -- so if they had an authentication cookie already for a site, I want them to not have to reauthenticate if at all possible.
Is there any way I can get the cookies from the main domain or does anyone have another suggestion of how I can transfer the cookies?
Update: Sorry, I didn't make it clear before, the cookie is only set if the visitor actively authenticates themselves by submitting a form on the user's site.
If you change the cookie domain to be more permissive (applying to more sub domains) you have no way to read the old, more restricted cookies except from the top level domain that used to work.
You will have to read the cookie, authenticate, and then write a new more permissive cookie before the cookie can be read by the subdomain.
You can roll out your migration logic in advance of the feature and hope you get most people. The rest will have to re-authenticate manually.
Personally I think they should have to re-authenticate.. it will only happen once, then they'll have the new ".domain.com" cookie.
But... One way to achieve this would be to check for the new cookie and when failing to find it, redirect to a new page on the main domain, providing the return url.
In that new page, check for the old style cookie, set the new style cookie, and redirect to the original url. if they don't have the old style cookie, redirect to the login area.
hope this helps.

How do I let a user sign in from a different domain on Authlogic?

[This is slightly different than a previous question about having multiple domains share the same cookie. It seemed like there wasn't an easy way to do that.]
I have a application at application.com. A customer has app.customer.com pointed at my site on Heroku, and I have everything set up so that it renders a specific version of app correctly. The issue is that I want a user at app.customer.com to be able to login. I believe authlogic is now setting the cookie on application.com, so while it verifies the credentials, no session on customer.com is ever created.
Since cookies cannot be shared across domains, you probably need to save an identifier in a database and also pass it through the url so when the client browser hits the new domain, it sends the token for the new domain session to see and match.
It should be a long cryptographically safe token, like a UUID to keep it from being guessed by attackers.
I'm not sure how the authlogic piece fits in though.

Resources