Session hijacking and Session fixation - asp.net

We have Session hijacking and Session fixation problem with our asp.net application.
We have implemented SSL also.
1.. I have added below code in web.config file.
<----
<httpCookies httpOnlyCookies="true" requireSSL="true" />
<forms loginUrl="Homepage.aspx"
protection="All"
timeout="20"
name=".ASPXAUTH"
path="/"
requireSSL="true"
slidingExpiration="true"
/>
--->
2... Encrypting formsathuntication ticket and adding to the cookie after user is athunticated.
<---
FormsAuthenticationTicket tkt;
string cookiestr;
HttpCookie ck;
tkt = new FormsAuthenticationTicket(1, uname, DateTime.Now, DateTime.Now.AddMinutes(20),false, "your custom data");
cookiestr = FormsAuthentication.Encrypt(tkt);
ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr);
ck.Path = FormsAuthentication.FormsCookiePath;
Response.Cookies.Add(ck);
-->
3.. I'm removing session variables and passing null value to ASP.NET_SessionID on logout page and Error page.
SessionHandler.EndSession();
Session.RemoveAll();
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
if (Request.Cookies["ASP.NET_SessionId"] != null)
{
Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20);
}
if (Request.Cookies["AuthToken"] != null)
{
Response.Cookies["AuthToken"].Value = string.Empty;
Response.Cookies["AuthToken"].Expires = DateTime.Now.AddMonths(-20);
}
HttpCookie authcookie = Request.Cookies[FormsAuthentication.FormsCookieName];
authcookie.Expires = DateTime.Now.AddDays(-1D);
Response.Cookies.Add(authcookie);
FormsAuthentication.SignOut();
still problem is not solved...

Is your problem session hijacking, or authentication hijacking?
Are you trusting session values without validating identity? (Note that session and authentication are not intrinsically linked in ASP.NET).
If you've implemented SSL, why is your session cookie still set to requireSSL="false"?
Research best-practice, and see for yourself where you've gone wrong. For example - http://www.troyhunt.com/2010/07/owasp-top-10-for-net-developers-part-3.html
To elaborate on point 2.
There are two cookies in use here, one is for Session, the other for FormsAuthentication.
The FormsAuth cookie identifies the user, and all reasonable steps need to be taken to keep this one secure. Typically, requiring SSL is a good step (as you've applied in the edit of your example). The Session cookie though, often doesn't come under as close scrutiny for developers, but depending on how you're using it can be just as sensitive. A session fixation steals the session, not the authentication.
An example:
UserA logs in, they are an admin user. They receive a FormsAuth cookie stating "This is UserA", they might also get a session cookie stating "This User Is Admin".
UserB gets a copy of the session cookie belonging to UserA (they might do this via interception, or even just by being on the same machine after UserA logs out if the session cookie isn't cleared).
UserB logs in, they are a "read-only" user (not admin). They receive a FormsAuth cookie stating "This is UserB", they then inject the session cookie stolen at step 2. Meaning they have a FormsAuth cookie stating "This is UserB", and a Session cookie stating "This User Is Admin".
Presto, UserB is now admin.
The problem here (as it relates to point 2 of my original list of concerns), is that the server didn't verify the identity of the user in relation to its session. You can do your best to try and link the Session and Forms authentication tickets together somehow, and definitely make certain you're encrypting (SSL). OR, you can stop storing sensitive data in the session (or at least reduce it). When it comes to my "This User Is Admin" example above, the better implementation is to use the ASP.NET Role and Profile providers in conjunction with the Membership provider. The three of them go hand in hand, and there's a lot of examples out there on how to use them to your advantage.
This is only one possible line of investigation though and as #JohnFx rightly pointed out, you really need a focused question here before you can expect a good answer. When it comes to security implementation, it's important to understand the concepts involved, instead of just throwing example code at the issue. Your example code provided thus far looks suspiciously similar to a CodeProject article discussing session fixation, but do you understand what it's trying to accomplish? Do you know if it even applies to the problem you're experiencing?

Related

FormsAuthentication.SignOut() does not expire the FormsAuthenticationTicket

First off, this is not a problem with the ASP.NET session not expiring, we clear, abandon, and delete every cookie on logout.
This is about FormsAuthentication.SignOut() not expiring the ticket when called and allowing someone who copies the content of the cookie to manually create the cookie somewhere else and still be able to acces everything that is meant to now be blocked off after the logout.
Here is the gist of our logout method:
HttpContext.Current.User = null;
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.Abandon();
HttpContext.Current.Session.RemoveAll();
HttpContext.Current.Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
We also let ASP manage the creation of the ticket and the authentication via our Web.config and whatever else manages FormsAuthentication. Here is what is in the config:
<authentication mode="Forms">
<forms name="COOKIENAME" loginUrl="~/PAGE_THAT_REDIRECTS_TO_LOGIN.aspx" defaultUrl="~/PAGE_THAT_REDIRECTS_TO_LOGIN_OR_PROPER_PAGE_IF_LOGGED_IN.aspx" cookieless="UseCookies" timeout="60" />
</authentication>
Now, why is this an issue? simple, it's a security concern as if someone gets the cookie and keeps it alive, they can access whatever the user matching the cookie can, even though the user has been disconnected.
Is there is a proper way to force the FormsAuthenticationTicket to expire?
I tried decrypting it, but everything is readonly, and I also tried to create a new expired ticket and encrypting it, but it doesn't overwrite the old one.
Thanks
Versions: .NET 4.5.1, ASP.NET (not Core)
The basic problem is with Microsoft .net Core cookie Managemnt, it does not handle the lifetime of cookies correctly.
I had face this issue several times, and mostly with .Net core now.
To solve this issue we need to override their cookie management class, and implement ITicketStore interface.
https://github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationOptions.cs#L136
Below article can help you with detail implementation.
https://mikerussellnz.github.io/.NET-Core-Auth-Ticket-Redis/
I hope it helps.

How to create ASP.NET Membership cookie properly?

I'm using the Membership API for my login system and a wierd thing has been bothering me. I allow user to choose whether to "Remember Me", which means whether to create a persistent cookie with one month expiration period.
In the Web.config, I wrote:
<authentication mode="Forms">
<forms timeout="60" />
</authentication>
This is supposed to be a default session cookie of 60 minutes.
In the code behind of the login page:
if(Membership.ValidateUser(UsernameTextBox.Text, PasswordTextBox.Text))
{
authCookie = FormsAuthentication.GetAuthCookie(UsernameTextBox.Text, RememberMeCheckBox.Checked);
if(RememberMeCheckBox.Checked)
authCookie.Expires = DateTime.Now.AddMonths(1);
Response.Cookies.Add(authCookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(UsernameTextBox.Text, RememberMeCheckBox.Checked));
}
The result however is strange. I seem to have created a persistent cookie of 60 minutes! How is this possible?
You are setting the cookie expiration time to be be 1 month, but the authentication ticket that it contains has not been modified. It has inherited the default value of 60 minutes from your web config.
You likely want to synchronize cookie expiration with the authentication ticket expiration, or alternatively set the cookie to have a very long expiry date.
What you need to do is
create a FormsAuthenticationTicket instance manually and set the
Expiration property of the instance.
Use FormsAuthentication.Encrypt() to encrypt the ticket
Add a cookie to the Response.Cookies collection containing the ticket, manually. (rather then using get/setAuthCookie(), which uses
the web.config settings).
Some example code is in the documentation for FormsAuthentication.Encrypt().

how to set the forms authentication cookie path

On the same IIS web site, I have two ASP.NET web applications called /foo and /bar. Both use forms authentication and I want users to be able to log in and out of both sites independently.
With the standard configuration for forms authentication, it seems to send a cookie path of "/" for the forms auth cookie. This means that when a user logs into /bar it logs him out of /foo which is undesirable behaviour for me.
The obvious solution seems to be this:
FormsAuthentication.RedirectFromLoginPage(username, false, Request.ApplicationPath);
This makes the forms auth cookie have the application path which allows the user to log into /foo and /bar independently :-) However there is a further and more nasty problem: If the user tries to log into /Foo (with a capital F), IIS directs them to the web application /foo, but they can never log in because the browser (chrome in this case) is case sensitive when deciding whether to send the cookie based on the cookie path.
This seems to be a common problem which every ASP.NET web app developer will face but I can't see a sensible solution for it. Please tell me i've missed something obvious?
Thanks
Andy
I assume you have already solved this issue somehow, but since I stumbled upon this question I thought I should add my few cents.
To solve the issue use different cookie names in web.config. Something like:
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH_FOO"
loginUrl="public/login.aspx" cookieless="UseCookies" slidingExpiration="true"/>
</authentication>
and
<authentication mode="Forms">
<forms name=".ASPXFORMSAUTH_BAR"
loginUrl="public/login.aspx" cookieless="UseCookies" slidingExpiration="true"/>
</authentication>
Dim ticket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
pUsernameEntered, _
DateTime.Now, _
DateTime.Now.AddMinutes(60), _
True, _
pOperatorID, _
FormsAuthentication.FormsCookiePath)
' Encrypt the ticket.
Dim encTicket As String = FormsAuthentication.Encrypt(ticket)
'create a cookie with the encrypted ticket
Dim authenticationCookie As New HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
'only create a persistent cookie if ticket persistent is checked
If (ticket.IsPersistent) Then
'give the cookie an expiration date outside of the forms authentication encrypted ticket
authenticationCookie.Expires = ticket.Expiration
End If
'save the cookie
HttpContext.Current.Request.Cookies.Remove(".cookiename")
Response.Cookies.Add(authenticationCookie)
In cookiename you can set you cookie name.
and in AddMinutes you can set your minutes values currently it is 60.

How to properly handle Forms Authentication Ticket when using a Cookie-less Session

I am pretty sure I do not have a unique problem, but I have searched all over google and this site and I haven't found a solid answer for what I am looking for. So I wanted to explain myself to see if I could get any help on this issue:
We (my co-workers and I) determined that we need have cookie-less Sessions because our users require multiple sessions to get their work done in a more productive fashion.
Example
Bob the user could have initiated a long running process in window A and in order to continue working Bob will open window B which spawns a new session. This is necessary in order to not disturb what is going on in window A. Every time Bob opens a new window, he has to log in again.
The Problem
I am not really sure if this is a real problem or not, hence my reason for asking. The problem I think I have discovered is that each time Bob logs in, the current Forms Authentication Ticket (and Cookie) are over-written. Now I do not understand how this is okay or why the previous Session/Window combo is still valid after Bob logs in a second time. Since the ticket was over-written doesn't that mean the first Session/Window combo should end because the ticket is no longer valid? This is with respect to:
Request.IsAuthenticated //Making sure the supplied ticket is valid
Questions
So since the Forms Authentication Ticket (and Cookie) are being over written, what does this mean?
Should I be concerned that the ticket (and Cookie) are being over written?
During login, should I be intercepting the ticket (if any) and checking for its expiration? If it is not expired should I try to renew the ticket or just make a new one?
FormsAuthentication.RenewTicketIfOld(ticket) //Just an example
If I am using a cookie-less session should I just use cookie-less Forms Authentication too? The point of doing this would be to make each Session/Window 100% independent of each other. No over-writing would occur anymore. Is there a draw back to this? I can't think of any.
PS: I know the cookie is just a container for what ever is being stored in it, like a Key Value pair.
Additonal Info...
Forms Authentication Ticket:
IsPersistent set to true
Ticket Version 2
Forms Cookie:
Key = FormsCookieName (from web.config tag)
Value = Hashed Ticket
Web.Config:
<sessionState
cookieless="true"
mode="SQLServer"
sqlConnectionString="..."
timeout="300"
regenerateExpiredSessionId="true" />
<forms name="FormsCookieName"
path="../"
loginUrl="Login.aspx"
protection="All"
timeout="300"
slidingExpiration="true" >
</forms>

ASP.NET: Authenticating user in code

I'm playing around with authentication and authorization to prepare for some task. I've created two pages: Login.aspx and Default.aspx. In config file i've set authentication to forms and denied unauthenticated users access:
<authentication mode="Forms">
<forms name="aaa" defaultUrl="~/Login.aspx" />
</authentication>
<authorization>
<deny users="?"/>
</authorization>
Then I've written some simple code to authenticate my user in Login.aspx:
protected void Page_Load(object sender, EventArgs e)
{
GenericIdentity identity = new GenericIdentity("aga", "bbb");
Context.User = new GenericPrincipal(identity, new String[] { "User" }); ;
Response.Redirect("~/Default.aspx");
}
When i run it, the redirection doesn't take place. Instead Login.aspx is called over and over because the user is not authenticated (Context.User.Identity.IsAuthenticated is false at every load). What am i doing wrong?
Context.User only sets the principal for the current request. Once the redirect takes place, the current request ends and a new one begins with the non-overridden principal again (which is apparently not authenticated). So, setting Context.User doesn't actually authenticate anything.
Using FormsAuthentication.SetAuthCookie() will set the user's cookie to a valid value accepted by the FormsAuthentication provider, or put the token in the URL. You can redirect to your heart's content because the cookie obviously sticks with the user for future requests.
From MSDN (em added):
With forms authentication, you can use the SetAuthCookie method when you want to authenticate a user but still retain control of the navigation with redirects.
As stated, this does not necessarily require cookies - the name is a little misleading, because it will still work via the URL if FormsAuthentication is in cookieless mode:
The SetAuthCookie method adds a forms-authentication ticket to either the cookies collection, or to the URL if CookiesSupported is false.
Use FormsAuthentication.SetAuthCookie(..). Or FormsAuthentication.RedirectFromLoginPage(..).
You need to actually set the user as authenticated. All of the following methods will work and let you actually get away from your login screen.
FormsAuthentication.Authenticate()
FormsAuthentication.RedirectFromLoginPage()
FormsAuthentication.SetAuthCookie()
Lots of ways to get to the same result.
You need to actually make a call to the formsAuthentication provider to set the login.
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, chkPersistLogin.Checked)
is a simple example
After creating the dummy Context.User, you need to perform a FormsAuthentication.SetAuthCookie or RedirectFromLoginPage method.

Resources