由于对我们的一些产品进行了渗透测试,当时看起来是一个“容易”解决的问题,现在却变成了一个棘手的问题。
当然,这并不是说它应该这样做,我的意思是为什么仅仅为当前的HTTPContext
**生成一个全新的会话会如此困难?奇怪!无论如何-我已经写了一个厚脸皮的小实用程序类来“做”:
(为代码格式/突出显示/Visual Basic道歉,我 * 一定 * 做错了什么)
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
字符串
它在请求的剩余部分工作正常,并正确地将自己标识为新会话(例如,HTTPContext.Current.Session.SessionID
返回新生成的会话标识符)。
令人惊讶的是,当下一个请求到达服务器时,HTTPContext.Session
(一个HTTPSessionState
对象)用正确的SessionID
标识自己,但将IsNewSession
设置为True
,并且为空,丢失了前一个请求中设置的所有会话值。
因此,从初始请求中删除的前一个HTTPSessionState
对象一定有什么特殊之处,这里有一个事件处理程序,那里有一个回调函数,处理跨请求持久化会话数据的东西,或者只是我遗漏了什么?
有谁有魔法要分享吗?
7条答案
按热度按时间bxpogfeg1#
我想分享我的魔法。实际上,不,它还没有魔法。。我们应该测试和发展代码更多。我只在with-cookie,InProc会话模式下测试了这些代码。将这些方法放在你的页面中,并在需要重新生成ID的地方调用它(请将你的Web应用程序设置为完全信任):
字符串
我一直在挖掘.NET源代码(在http://referencesource.microsoft.com/netframework.aspx中可用),发现没有办法在不破解会话管理机制内部的情况下重新生成SessionID。所以我就这么做了-破解SessionStateModule内部字段,这样它就会将当前Session保存保存到一个新的ID中。也许当前的HttpSessionState对象仍然有以前的ID,但是AFAIK SessionStateModule忽略了它。当它必须在某个地方保存状态时,它只使用internal _rqId字段。我尝试过其他方法,比如将SessionStateModule复制到具有重新生成ID功能的新类中,(我计划用这个类替换SessionStateModule),但失败,因为它当前有对其他内部类的引用使用反射的缺点是我们需要将应用程序设置为“完全信任”。
哦,如果你真的需要VB版本,试试这些:
型
vshtjzan2#
如果您有安全意识,并且希望此答案的C#版本删除旧字段,请使用以下内容。
字符串
ffdz8vbo3#
正如Can Gencer所提到的- ReleaseItemExclusive不会从存储中删除旧会话,这会导致该会话最终过期并在Global. asax中调用Session_End。这给我们的生产带来了一个巨大的问题,因为我们正在清除Session_End中的线程标识,因此-用户会自发地失去线程上的身份验证。
所以下面是正确的代码,工作。
字符串
6tqwzwtp4#
你有没有考虑过使用HttpSessionState.Abandon method?这应该会清除所有内容。然后启动一个新的会话,并使用上面代码中存储的所有项目填充它。
Session.Abandon();
应该足够了。否则,如果它仍然很顽固,你可以尝试多打几个电话:字符串
yebdmbv45#
你不能只设置:
字符串
在web.config中,然后使用Ahmad建议的解决方案?
dgsult0t6#
登录asp.net后如何更改会话ID
对于那些现在正在搜索并看到所有这些反射黑客和正在与会话固定问题作斗争的人来说,进入asp.net创建新会话ID的唯一方法是伪造一个
SessionIDManager
,为您的登录页面返回null。这样ASP.NET就认为浏览器从未发送过cookie。以下是步骤:
CustomSessionIDManager
,注意YourLoginController/LoginMethod
:字符串
db2dz4w87#
对于MVC 4,请输入以下代码:
字符串