Generating a new ASP.NET session in the current HTTPContext

前端 未结 6 1338
终归单人心
终归单人心 2020-11-27 03:29

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.

6条回答
  •  -上瘾入骨i
    2020-11-27 03:55

    As Can Gencer mentioned - ReleaseItemExclusive doesn't remove old session from the store and that leads to that session eventually expiring and calling Session_End in Global.asax. This caused us a huge problem in production, because we are clearing Thread identity in Session_End, and because of this - users were spontaneously losing authentication on thread.

    So below is the corrected code that works.

    Dim oHTTPContext As HttpContext = HttpContext.Current
    
    Dim oSessionIdManager As New SessionIDManager
    Dim sOldId As String = oSessionIdManager.GetSessionID(oHTTPContext)
    Dim sNewId As String = oSessionIdManager.CreateSessionID(oHTTPContext)
    
    Dim bIsRedir As Boolean = False
    Dim bIsAdd As Boolean = False
    oSessionIdManager.SaveSessionID(oHTTPContext, sNewId, bIsRedir, bIsAdd)
    
    Dim oAppContext As HttpApplication = HttpContext.Current.ApplicationInstance
    
    Dim oModules As HttpModuleCollection = oAppContext.Modules
    
    Dim oSessionStateModule As SessionStateModule = _
      DirectCast(oModules.Get("Session"), SessionStateModule)
    
    Dim oFields() As FieldInfo = _
      oSessionStateModule.GetType.GetFields(BindingFlags.NonPublic Or _
                                            BindingFlags.Instance)
    
    Dim oStore As SessionStateStoreProviderBase = Nothing
    Dim oRqIdField As FieldInfo = Nothing
    Dim oRqItem As SessionStateStoreData = Nothing
    Dim oRqLockIdField As FieldInfo = Nothing
    Dim oRqStateNotFoundField As FieldInfo = Nothing
    
    For Each oField As FieldInfo In oFields
        If (oField.Name.Equals("_store")) Then
            oStore = DirectCast(oField.GetValue(oSessionStateModule), _
                                SessionStateStoreProviderBase)
        End If
        If (oField.Name.Equals("_rqId")) Then
            oRqIdField = oField
        End If
        If (oField.Name.Equals("_rqLockId")) Then
            oRqLockIdField = oField
        End If
        If (oField.Name.Equals("_rqSessionStateNotFound")) Then
            oRqStateNotFoundField = oField
        End If
        If (oField.Name.Equals("_rqItem")) Then
            oRqItem = DirectCast(oField.GetValue(oSessionStateModule), _
                                 SessionStateStoreData)
        End If
    Next
    
    If oStore IsNot Nothing Then
    
        Dim oLockId As Object = Nothing
    
        If oRqLockIdField IsNot Nothing Then
            oLockId = oRqLockIdField.GetValue(oSessionStateModule)
        End If
    
        If (oLockId IsNot Nothing) And (Not String.IsNullOrEmpty(sOldId)) Then
            oStore.ReleaseItemExclusive(oHTTPContext, sOldId, oLockId)
            oStore.RemoveItem(oHTTPContext, sOldId, oLockId, oRqItem)
        End If
    
        oRqStateNotFoundField.SetValue(oSessionStateModule, True)
        oRqIdField.SetValue(oSessionStateModule, sNewId)
    
    End If
    

提交回复
热议问题