How to preserve authentication for ASP.NET Forms authentication cookie, Http to Https (different domains) and back? - asp.net

We have a non-SSL ASP.NET web app that allows a user to login (ASP forms authentication, inproc).
Once authenticated, we redirect their browser to an external, SSL secured page on another web site / domain altogether that we do not control.
The client is redirected back to a pre-configured url on our original http web app when done.
However, the customer is then asked to "re-login" again on our side which is undesired...
It seems the forms authentication cookie is destroyed when transitioning between HTTP and HTTPS and back again.
How can I keep the forms authentication cookie alive so that the customer does not have to re-authenticate on the round trip?

It's not being destroyed; you're not authenticating on your domain, so the cookie's not being set on your domain, and thus requests on your domain will not contain said authentication cookie.
This is GOOD. If this didn't happen, then every cookie from every domain you ever visited would get sent with every request. Which is obviously 1) crazy and 2) a security hole. Setting a cookie on mydomain.com should never be visible to pages on myotherdomain.com.
If you're using a 3rd party authentication system, like google, facebook, etc, they'll all have some sort of callback token that you'll have to process and set your own cookies.

Consider to set cookie's domain property for your cookies with more specified can be found here or try this code:
Response.Cookies["your_cookie_name"].Domain = "yourdomain.com";

You're looking for a Single Sign On solution.
It might be a little overkill for your problem, for which you might just want to get the same domainname. But if that isn't an option you might want to take a look at:
Windows Identity Foundation

Related

Cookie does not persist across redirect in production

I'm building a web application that uses cookies to track the user session. These cookies work flawlessly in development on localhost but they aren't working correctly in production. I suspect this is because I have some cookie settings misconfigured but I'm not sure which.
One thing to note is that the webapp runs at app.goldsky.com and the api runs at api.goldsky.io (note the different TLDs).
The application I'm building uses a tool called WorkOS for user authentication.
The authentication flow is as follows:
User visits website, enters their email and presses the login button
Request is sent to backend (api.goldsky.io)
Backend generates an authentication URL using the WorkOS SDK (of the form api.workos/...) and sends this to the frontend
the frontend navigates to this WorkOS authentication URL and proceeds through the auth flow
If successful, WorkOS redirects the user to my backend (api.goldsky.io/auth/workos/callback)
My backend generates a session token, sets a secure, httpOnly, path=/ cookie with the session token (goldsky_session=...) and redirects the user back to the webapp (app.goldsky.com)
In localhost this all works flawlessly. However, in production I don't see the cookie persist after step 6 completes.
In production, the response to step 5 contains the cookie
however after the redirect back to the webapp, the cookie seems to disappear. Here's the request to app.goldsky.com (the redirect from step 6) and it doesn't have the cookie header.
and just for completeness, here's a screenshot of the cookies for app.goldsky.com - it's empty:
By comparison, the final redirect on localhost contains the cookie:
How come my cookie does not persist after redirecting from api.goldsky.io to app.goldsky.com? Do I need to set the Domain attribute for the cookie? If so, what should I set it to? Maybe this is a SameSite problem?
Turns out I had an nginx misconfiguration issue which was rejecting requests to specific paths. Nginx was only allowing requests to /auth and a few others. My login logic was under /auth but the user query was at /user which nginx was rejecting.

Forms Authentication Cookie value vulnerability in asp.net

In asp.net, I am able to login using forms authentication as usual, copy our auth cookie value, log out, add the cookie artificially to the client using the 'Edit This Cookie' addon for Chrome, refresh the (anonymous) landing page and hey presto i'm logged in again. This seems to be a vulnerability - is there any way of fixing it using the the standard forms auth or will I have to do something like use a custom Authorize attribute which overrides the existing one in asp.net mvc?
I don't think this is a bug per se. The following happens during forms authentication
You provide a username/password to the server
Server validates username/password
If valid, the server then sends an encrypted authentication ticket (cookie) to the client with the expiration time (set in the web.config forms authentication section) and username (all encrypted)
On each request that requires authorization, the cookie is decrypted on the server, expiration time is checked and username is used to see if authorized (or getting that role for the requested resource).
When you logout, the expiration time on the cookie is set in the past, therefore, it is not longer a valid cookie
Now, as to why you are seeing what you are seeing... You are copying the cookie before you logout. Thus your copied cookie never registers the logout (moved expiration time). When you reattach, you still have a valid auth cookie. Now, if your forms authentication timeout is set to...let's say 20 minutes...this method would fail if you copy the cookie and wait 21 minutes as by that time, it has expired.
Cookies are always vulerable and we can't do much about that. What we can do is prevent someone from stealing the cookies.
Regarding ASP.NET MVC it does a good job to avoid stealing cookies. Some of the main things it does by default as part of security are:
Encode the strings that are rendered to the view (if you are using Razor don't know about others) to prevent from XSS attacks.
Request validation (stop potentially dangerous data ever reaching the
application).
Preventing GET access for JSON data.
Preventing CSRF Using the Antiforgery Helpers
Regarding cookies Microsoft provides HttpOnly feature and this helps to hide the cookies from javascript. The Forms authentication that you are talking about is a HttpOnly cookie means someone can't steal that through JavaScript and it's more safe.
You can do that with any cookie/s. You can inspect/copy all the cookies from any given domain, and spoof if you want. You can do that to yourself (only) because its your PC (or user logged in to PC). Obviously if you're on a shared PC, that is a problem (across all your info).
The act of "copying your cookie" is in fact one way malware attempts to steal/hijack your identity (or current session on some web site). That said, unless you have some malware, you can't just "copy cookies" of someone else.
Assuming logout is done, you can ask users to close their browsers so the expired cookie is removed from the (file) system.

Asp.net - Using SSL to prevent cookie replay attack

I'm looking to put SSL into place to prevent cookie replay attacks on our site.
The site is using .NET forms authentication. Do I just need to enable SSL for the login page or would it be every page behind the forms authentication that needs to be secure?
THanks
You would need to enable SSL for every page where the browser is instructed to send the authentication ticket cookie. By default, that would mean every page on your website, although when writing the cookie to the browser you can instruct it to only send it over HTTPS or to limit it to certain paths.
But in general it would mean SSL protecting every page on your site, not just your sign in page.
.Net websites transfer non only the viewstate but any cookies back to the server on postback. This impacts your security in that someone using firesheep (or a similar tool) could easily pick up an authentication cookie, not on login, but when a user postsback via a button press, or ajax event several pages into the application.
If you have access to IIS you can not only enable SSL use, but force it.

ASP.NET Login via SSL doesn't persist when switching to non-SSL

I have an application I would like to force SSL on the login page and on the page that the CC is entered on. I would prefer to keep the rest of the application free of SSL.
I have the code working to force SSL on certain pages, and remove SSL on others. The problem I have is that if I log in with SSL enabled the user is only authenticated on the pages that are SSL. The reverse holds true as well, if the user logs in without SSL they are only authenticated on pages without SSL.
What can I do to have this persist between the two. Is this using cookies or the session?
Thanks!
Classically, one would use the session for this.
You can use cookies as well.
In either case, you need to keep in mind that they can be spoofed, so you want to only keep a "logged in" token that you can verify on them.

Asp.net forms authentication and multiple domains

I have two domains, domain1.com and domain2.com pointing at the same asp.net website which uses asp.net build in form authentication. The problem is that even if the domains point to the same website the user only get authenticated for one domain at a time. So if he uses www.domain1.com first and then visits www.domain2.com it's the same website in the back but he only is authenticated for www.domain1.com. The same thing happens if he uses www and not www when visiting the sites.
This is what I use to login:
FormsAuthentication.RedirectFromLoginPage(username, cookie.Checked);
To check login:
User.Identity.IsAuthenticated
How can I make the user gets authenticated for all domains that points to the same website?
What you're after is a Single Sign-on solution.
As ASP.NET authentication is at it's heart generally cookie based, there are two things to look at:
Set your cookies correctly.
Bounce your users to the alternative domain during signup.
Looking at both of these in more depth:
1. Setting cookies correctly
You need to ensure that ASP.NET is writing the authentication ticket cookies to the root domain, rather than the explicit domain this is done using the domain attribute of the forms element:
<forms
name="name"
loginUrl="URL"
defaultUrl="URL"
domain=".example.com">
</forms>
You should set your domain to ".example.com" - note the leading period - this is the key. This way requests to example.com and www.example.com will both read the cookie correctly, and authenticate the user.
2. Bounce users to the alternative domain
What we have implemented on a few sites that use a single sign on is a round trip login process. The user authenticates on the first domain, we encrypt the login details, and redirect them to a known page on the second domain, log them in there, and then redirect back to the original server.
This client side redirection is important - cookies are only written when there is a response back to the client, and the browser has to visit the second domain to actually see the cookies.
Other details to consider in this sort of set-up:
You probably want to have a timeout on the encrypted sign-in details - so that recalling that URL from the browser history doesn't automatically log the user in.
If the domains are on different servers, you will need to ensure that either the machine keys are configured the same, so that you can encrypt and decrypt the details correctly, or use some other shared key.
You will probably want to have a mechanism in place to recall the users ReturnUrl from the original server so that you can send them back to the correct place.
You could also take a look at "Forms Authentication Across Applications"
You could try setting cookieless="true".
You should read Explained: Forms Authentication on MSDN. They cover Cross-Domain Authentication.

Resources