views:

1123

answers:

2

As a result of a penetration test against some of our products in the pipeline, what looked to be at the time an 'easy' problem to fix is turning out to be a toughy.

Not that it should of course, I mean why would just generating a brand new session for the current HTTPContext be so difficult? Bizarre! Anyway- I've written a cheeky little utility class to "just do it":

(apologies for code formatting/highlighting/Visual Basic I must be doing something wrong)


Imports System.Web
Imports System.Web.SessionState

Public Class SwitchSession

    Public Shared Sub SetNewSession(ByVal context As HttpContext)
        ' This value will hold the ID managers action to creating a response cookie
        Dim cookieAdded As Boolean
        ' We use the current session state as a template
        Dim state As HttpSessionState = context.Session
        ' We use the default ID manager to generate a new session id
        Dim idManager As New SessionIDManager()
        ' We also start with a new, fresh blank state item collection
        Dim items As New SessionStateItemCollection()
        ' Static objects are extracted from the current session context
        Dim staticObjects As HttpStaticObjectsCollection = _
            SessionStateUtility.GetSessionStaticObjects(context)
        ' We construct the replacement session for the current, some parameters are new, others are taken from previous session
        Dim replacement As New HttpSessionStateContainer( _
                 idManager.CreateSessionID(context), _
                 items, _
                 staticObjects, _
                 state.Timeout, _
                 True, _
                 state.CookieMode, _
                 state.Mode, _
                 state.IsReadOnly)
        ' Finally we strip the current session state from the current context
        SessionStateUtility.RemoveHttpSessionStateFromContext(context)
        ' Then we replace the assign the active session state using the replacement we just constructed
        SessionStateUtility.AddHttpSessionStateToContext(context, replacement)
        ' Make sure we clean out the responses of any other inteferring cookies
        idManager.RemoveSessionID(context)
        ' Save our new cookie session identifier to the response
        idManager.SaveSessionID(context, replacement.SessionID, False, cookieAdded)
    End Sub

End Class

It works fine for the remainder of the request, and correctly identifies itself as the new session (e.g. HTTPContext.Current.Session.SessionID returns the newly generated session identifier).

Surprise surprise then, that when the next request hits the server, the HTTPContext.Session (an HTTPSessionState object) identifies itself with the correct SessionID, but has IsNewSession set to True, and is empty, losing all the session values set in the previous request.

So there must be something special about the previous HTTPSessionState object being removed from the initial request, an event handler here, a callback there, something which handles persisting the session data across requests, or just something I'm missing?

Anybody got any magic to share?

A: 

Have you considered using the HttpSessionState.Abandon method? That ought to clear everything. Then start a new session and populate it with all the items you stored from your code above.

Session.Abandon(); should suffice. Otherwise you could try to go the extra mile with a few more calls if it's still being stubborn:

Session.Contents.Abandon();
Session.Contents.RemoveAll();
Ahmad Mageed
Unfortunately this approach appears to reuse the same session identifier. I require a new session identifier to be generated :(
Rabid
A: 

Can you not just set:

<sessionState regenerateExpiredSessionId="False" />

in web.config, and then use the solution suggested by Ahmad?

Jibberish
Unfortunately not, it still retains the active `SessionID`, which gets used when the next request hits. What is the meaning of 'expired' in this context though? I haven't expired the session- I can't see a way to 'expire' the session other than expiring the client cookie. That doesn't help my active `HTTPContext` though.But even still, using this method- after I've abandoned the session and removed all the contents, I then authenticate my user and place something in the session, because the session has been 'abandoned', it is empty on the next request. :( :( :(
Rabid