How to handle ASP.NET_SessionId Cookie in ASP.NET MVC Application - c#

I have Asp.NET MVC application which gets logged in after secure Id and password authentication.
After login, when I go to developer tools in Web Browser and Copy the ASP.NET_SessionId Cookie and paste it in another browser without login with Id and password, It gets logged in.
Where this cookie is created? And how I can handle this vulnerability?

You are describing "session hijacking"
You should ensure that ASP.net requires https, and that cookies are not accessible to client side script, by adding this to web.config
<httpCookies httpOnlyCookies="true" requireSSL="true" />
You might also implement something like the SecureSessionModule in this article which generates some additional measures
Note the caveats
https://learn.microsoft.com/en-us/archive/msdn-magazine/2004/august/wicked-code-foiling-session-hijacking-attempts

Related

urlRewrite in web.config to protect aspx page

I created a custom login/authentication page.
When the user authenticates and is valid, my site:
Response.Redirects("destinationpage.aspx");
Because I'm not using Forms Authentication, I need another way to protect "destinationpage.aspx".
Is there a way to use urlRewrite in web.config to redirect users to "customlogin.aspx" to authenticate before being able to reach "destinationpage.aspx"?

Forms Authentication Across Applications has no cookie

I have two applications. The first one is an ASP.NET 4 MVC application that requires authentication. The second is an app that will handle the authentication and set the forms authentication cookie.
On the authorizing app, I call
FormsAuthentication.SetAuthCookie(username, false);
and then I do a simple Response.Redirect back to my MVC application.
In the MVC app, I am making a custom filter that inherits from AuthorizeFilter. On the OnAuthorization method, I was going to decrypt the cookie and grab some additional user data from the authorized user.
My problem is, that
HttpContext.Current.Request.Cookies
has nothing in it. I have checked out fiddler, and the authentication app correctly sets the cookie, and the MVC application gets the cookie, but when it gets to my filter, there is nothing there.
My web.config has in both applications has the exact same setup:
<forms
name=".ASPXFORMSAUTH"
protection="All"
path="/"
timeout="30"
enableCrossAppRedirects="true"
domain="localhost"/>
And I have setup both with the same machineKey to be able to decrypt the cookie. The problem is, I am not seeing any cookie in my OnAuthorization method within my MVC filter.
Right now both applications are running on my local IIS instance.
All the weird behavior was due to the httpRuntime between each application being different. My MVC application was set to 4.5 while my application that was setting the cookie was 4.0. Apparently there was a change in how the crypto happens behind the scenes, and therefore when the cookie came through the pipeline, it would get stripped out as ASP.NET couldn't decrypt it.
I came across this when I manually tried to decrypt the cookie by setting the name property different. That way I could access the cookie and try to dectypt, but at that point I would get an exception.
I found the following link led me in the right direction: Sharing a cookie between two websites on the same domain
By setting the compatibility mode setting on the machine key, the cookie came through just fine and could be decrypted.

Shared login in two MVC Projects? Why?

Imagine when you create a new MVC4 Project and you start registering an account using SimpleMembership and you logged using Remember Me checkbox.
Now, when you create another MVC 4 Project, the application tries to loggin using the previous account, although throws an error because it does not exist. I mean, if a do a login in a web page, the another one uses the same account.
How can avoid this, I guess has to be with ForgeryTokens or something like that
Customize the name of the cookie so that it's unique per application.
<authentication mode="Forms">
<!-- **Defaults** timeout="30" slidingExpiration="true" -->
<forms name=".MyApplication" defaultUrl="~/" loginUrl="~/LogIn" />
</authentication>
if you are using a single sign on mechanism then it is a exceptionable scenario but if you do not wish to allow the same authentication with same account to another website then make sure the web.config file for both projects must have a different machine keys.
Also, this is happened because of cookies on your machine is set to true, to create cookies file and allow access to other project using this cookies details.
< Authentication />
It happens because when the web page is served the browser sees localhost as the domain name. It saves the cookie for localhost.
When you host another website on the same server with localhost, then the browser sends the same cookie again.
If you are using the same cookie name in both the applications, then the system will try to think that the user is already authenticated and you will get the error.
You can change the cookie name in web.config file.
Read this:
Can I change the FormsAuthentication cookie name?

How to check if a cookie exists even if it was created in another application? (using JS or C#)

I have several applications and one of them is a central application that manages authentication, and where a LogOn page is imported from as an IFrame to the other applications.
When the userName and password are correct, I create a cookie named userInfo.
Now, in the current app, I want to check if the cookie of userInfo exists. I think I should check it exists in the browser (in client side).
It must be possible, so how can I do it ?
Thanks in advance.
Cookies cannot be shared cross domain. If your applications are not hosted on the same domain you have to forget about this. It won't work because browsers (for obvious security reasons) do not send cookies cross domain. There are other ways to implement cross domain single sign on (see the second part of my answer).
Now let's suppose that your applications are on the same domain and you have multiple applications spread over different sub-domains of the root domain:
login.foo.com
app.foo.com
xxx.foo.com
and you want to share authentication between those sub domains. All you have to do is specify set the domain property in your web.config to the root domain:
<authentication mode="Forms">
<forms
loginUrl="https://login.foo.com"
requireSSL="true"
protection="All"
timeout="120"
domain="foo.com"
slidingExpiration="false"
name="sso" />
</authentication>
The same configuration should be applied to the web.config of all applications. And that's pretty much all you need to do. Once the user is authenticated on one of the sub domains he will automatically be authenticated on the others thanks to the fact that cookies can be shared cross sub domains.
If you want to achieve cross domain single sign on then you will have to take a different approach. You could use the same machine keys between the different applications to encrypt the authentication token. Here are the steps:
User navigates to https://foo.com and is presented with a Logon screen because he is not authenticated on this domain yet.
The user authenticates and an authentication cookie is emitted and valid for the foo.com domain.
Now the user needs to go to https://bar.com and be automatically authenticated on this domain. On some page on https://foo.com you could create a form containing the value of the authentication cookie to be posted:
<form action="https://bar.com" method="post">
<input type="hidden" name="token" value="PUT THE VALUE OF THE AUTHENTICATION COOKIE HERE" />
<button type="submit">Go to bar.com</button>
</form>
The user submits the authentication cookie to the bar.com. The script that receives this form submission reads the authentication token value that was posted and uses the FormsAuthentication.Decrypt method to decrypt the authentication ticket and read the user name. Since both applications on foo.com and bar.com use the same machine keys, the ticket that was encrypted on foo.com will be successfully decrypted by bar.com
The script at bar.com having extracted the authenticated username from the token, it emits a forms authentication cookie valid on bar.com using the FormsAuthentication.SetAuthCookie method.
The user is now authenticated on bar.com
The whole security of this model relies on the fact that SSL is used when POSTing the forms authentication token from foo.com to bar.com so the token cannot be captured by a man-in-the-middle and that both applications share the same machine keys for encrypting and decrypting those tokens.

Session management and linking user accounts with OpenID, in ASP.NET

I am currently playing with DotNetOpenAuth to make an ASP.NET (C#) website use OpenID instead of the normal login-password routine for user and session handling.
Up till now, I have added the DotNetOpenAuth.dll into my project and tried a test login page with the following:
<rp:OpenIdLogin ID="OpenIdLogin1" runat="server" />
When I run the page, I enter a valid myopenid url and the website redirects to the myopenid page, where I enter my password, and upon success, it returns back to my default.aspx, due to the following in my web.config:
<authentication mode="Forms">
<forms defaultUrl="/Default.aspx" loginUrl="~/Login.aspx"/>
</authentication>
Now that the user is "logged in", how can handle my session? At the moment, I don't know how I can, for example, check if the session is still alive or how to terminate the session.
My basic question is, how can I manage the session once the user is authenticated with OpenID ?
[Update]
I am now using the following to check for authentication: HttpContext.Current.User, and with that I can now check if a user is authenticated with a session.
Now is there a possible way on how I can "link" user details that are stored in my database with an openid account?
OpenID logins with the OpenIdLogin control are (by default) no different than a username+password login from ASP.NET's point of view. As you've discovered HttpContext.Current.User is set on each incoming HTTP request based on an HTTP cookie that ASP.NET FormsAuthentication sends to the browser in order to keep the session consistent from request to request. While you're in a page or its code-behind, the Page.User property is an even more convenient means.
But if you're doing access control, rather than check whether there's a logged in user in every page, it's best to use the <authorization> tag in your web.config file to force the user to be logged in before accessing certain pages or directories of pages.
As far as linking user details, the key you want to associate with your users' details is the OpenID Claimed Identifier, which is what OpenIdLogin automatically assigns to the Username value for FormsAuthentication. So you can retrieve or store user details in your database based on the value of HttpContext.Current.User.Identity.Name, which will be the reliable and proven unique value for each user.

Categories