Reputation: 6971
I am having trouble with a security issue of asp.net. On log out I want to make sure the session is destroyed so that someone can't take the same sessionid and auth cookies and edit there cookies and the server still responses to the session.
FormsAuthentication.SignOut();
Session.Abandon();
Session.RemoveAll();
Session.Clear();
I have also tried to write new cookies to the client
// clear authentication cookie
HttpCookie cookie1 = new HttpCookie(FormsAuthentication.FormsCookieName, "");
cookie1.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie1);
HttpCookie cookie2 = new HttpCookie("ASP.NET_SessionId", "");
cookie2.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie2);
I have tried using the following in different orders and still no dice. I can am still logged in if I use the original sessionid and Auth cookies. I want the server to totally forget about that sessionid when I logout. Is this even possible ?
Upvotes: 4
Views: 9744
Reputation: 3184
The not programmatic way to make sure all session/cookie is wiped on the server side, is to add (if not present) or change (if present) machine key in application's web.config
It can be done via IIS Manager by selecting an application, and in ASP.NET section select "Machine Key", uncheck all checkboxes and hit Generate Keys then hit Apply
Please note this is not for a single user, it will kick out all users.
Upvotes: 1
Reputation: 4312
If You point on browser back button, I use bellow code (vb, but You can convert it) :
web.config:
<sessionState timeout="20" regenerateExpiredSessionId="true"/>
avsessexp.js (auto refresh page if is inactive after 15mins) :
var BeatTimer;
function StartCheck() {
if (BeatTimer == null) {
BeatTimer = setInterval("CheckBeat()", 900000);
}
}
function CheckBeat() {
PageMethods.PokePage();
}
and call StartCheck
function in every page (<body onload="StarCheck();">
)
in header of every page I put :
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache, no-store, max-age=0, must-revalidate" />
<meta http-equiv="expires" content="0" />
Module1.vb
Public Sub CheckSession()
With HttpContext.Current
.Response.Cache.SetExpires(DateTime.UtcNow.AddSeconds(-1))
.Response.Cache.SetCacheability(HttpCacheability.NoCache)
.Response.Cache.SetNoStore()
If .Session.IsNewSession = True Then LogOut()
'there You can put some code checking is user logged, ...
End With
End Sub
Public Sub LogOut()
With HttpContext.Current
.Session.RemoveAll()
.Session.Clear()
.Session.Abandon()
Try
.Response.Cookies.Add(New System.Web.HttpCookie("ASP.NET_SessionId", ""))
Catch ex As Exception
End Try
.Response.Redirect("Default.aspx")
End With
End Sub
and, in every page (code-behind) :
<System.Web.Services.WebMethod(EnableSession:=True)> Public Shared Sub PokePage()
CheckSession()
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then CheckSession()
End Sub
If You try click browser back button after logout, CheckUser
will prevent back to prev page, and always redirect user to login page.
It's very important to use on every page/master page <asp:ScriptManager runat="server" id="sm1" EnablePageMethods="True"><asp:ScriptManager>
p.s. sorry for my weak English.
Upvotes: 0
Reputation: 5817
The server does forget about everything related to that session and so make that session id invalid when you use Session.Clear()
.
As msdn documentation says:
Removes all keys and values from the session-state collection
So even if someone uses the same session id there will be no information attached to it in the server.
[Edit]
As Erik Funkenbusch points, my solution only works if you store authentication information in the session (obviously). This won't work if you have specific cookies for your authentication system.
Upvotes: 2
Reputation: 93424
There is no way, on the server side, to clear an authentication session permanently. You can clear the cookie, but If someone has made a copy of it, they can simply re-use it and they will get access to the site. Auth cookies are encrypted validation tickets, which means that the site decrypts them, and validates that they decrypt correctly and are not expired. If that's the case, then the auth cookie is valid.
Unfortunately, there's no way around this, short of using a short expiration value and updating the expiration date on a sliding window, but that means if the user is idle for a few minutes they will have to log in again.
There is no "session id" associated with an authentication ticket, although you could certainly generate a unique ID and store it in the ticket and then store that id on the server and compare it on each request to add an additional layer of security. When you want to kill that cookie, you clear whatever ID on the server and they can no longer log in, even if the ticket is otherwise valid.
Session cookies on the other hand do have id's and are associated with internal storage mapped to that ID, so when you clear the session you also delete the storage... if you reuse that cookie then it's just going to get null data.
You can also add more security by always using encrypted cookies, and using HTTPS. HTTPS does not store the cookies in a way that they can be acquired and re-used (they're encrypted with the SSL session, and once that SSL session is done the cookies are unusable).
Another option is to use non-persistent cookies, which don't get stored on the server.. although they can still be captured by man in the middle attacks.
To understand why there is no way around the problem, you have to understand that authentication cookies are intended to be long lived, and stored on the users computer.. When you come back, it can be a different session. Therefore, the only way to know if the users is authenticated is to simply rely on whether the cookie can be decrypted using the servers credentials (typically machine key). This means there is deliberately no link between a session and an authentication ticket.
Upvotes: 7