ASP.Net Session Swapping – Why it happens and what can be done about it?
Referring my recent post from the Premier Developer Blog.
Kernel Cache is a powerful and well-known feature introduced in IIS 7 and found in all later versions. It’s the highly performant server level cache that very efficiently delivers frequently used content. Since the cache is in kernel memory, it is served even before the request reaches the IIS pipeline and, hence, it’s lightning fast. The problem arises with ISAPI components if they are attaching session cookies on the content in Kernel cache, then it is possible to run into a “session-swap” issue. In other words, a session for userA gets assigned to userB. This issue can happen on IIS 7 onwards including IIS 8 and IIS 8.5 versions.
Kernel cache has a very strict policy for what gets stored in this cache and how it gets scavenged. If any content that meets this criteria also has the session cookies attached to it by an ISAPI component, then content still gets cached. The subsequent requests from other users will find the content in the session cache and in process will also get the session cookies for the other user. That’s the mechanism for session swap. This does not happen for managed components since IIS can better track how managed components are manipulating responses. Hence, if any managed component attaches a session cookie to a content that can potentially be stored in the kernel cache, that response content does not get stored in the kernel cache. However, ISAPI components are not cache aware and hence the issue.
The guidelines for ISAPI components regarding the kernel cache suggest that components either make themselves cache-aware by using the FilterEnableCache metabase property or disable caching for a specific response each time they perform a set-cookie operation on the response. This becomes tricky when using third-party components since you don’t have control of the ISAPI source code. The only option in that case is to disable the Kernel mode cache.
Disabling the kernel cache is a configuration change. If it is not locked at the applicationhost.config level, the applications can choose to override. In a multi-tenant environment, you might wonder about how to determine if any applications accidentally enable this? Kernel cache provides a set of performance counters that can be monitored for any such activity. It’s important to note, however, the kernel cache is controlled by http.sys so restarting IIS does not have any impact on the values of the performance counters. It is quite possible to keep seeing stale values in the performance counters even when the kernel cache is disabled, misleading you to believe that the cache is still being utilized. When tracking the perfmon data, it will also be observed that when performing an IIS reset, the aggregate counters such as Total URIs cached, Total Hits, Total Misses etc will go down to zero momentarily and then bounce back the original stale values. Since the kernel cache is being handled by http.sys and this driver is never restarted, the aggregate counters never lose their values.
Perfmon counters interact with the IIS Admin Service for monitoring purposes. Since an IIS Reset causes this service to stop and restart, perfmon is not able to read the counter values during that time and hence the momentary zero values. This does not indicate any changes in the actual values of the counters, rather, that the values were simply not availably for that time when the admin service was restarting. Restarting the HTTP service using the “NET STOP HTTP” command will reset these counters to zero.
As an effective monitoring strategy for identifying Kernel cache usage, it is recommended that teams monitor the “Current URIs cached” performance counter and alert if the value for this counter goes above zero. The other counters specified here can be tracked for post-mortem purposes. Typical monitoring products such as Systems Center Operations Manager can be used to monitor and alert on these performance counter values.