Session Fixation & Forms Authentication Token Termination in ASP.NET), I talked about ways to mitigate two types of session related vulnerabilities in an ASP.NET MVC 4 application. One of these vulnerabilities is also present in many WCF web services. In one mode of operation, WCF web services can authenticate users and issue forms authentication cookies. Since this token contains an encrypted set of values and resides only on the client-side, the server cannot choose to invalidated that token and end a user’s authenticated session. This allows attackers to continue using stolen tokens, even after the user logs out.
One solution for fixing this vulnerability is to issue an ASP.NET_SessionId cookie and to tightly couple it with the forms authentication cookie as described previously. Whenever a web service request is issued, the ASP.NET_SessionId value should be referenced to determine if the session store contains the username and it matches the value stored by the forms authentication token. This approach is sound; however, my implementation is experimental. I’m not a WCF or ASP.NET expert.
In my first attempt to implement this model, I tried using the built in Windows Communication Foundation Authentication Service (System.Web.ApplicationServices.AuthenticationService). There were some critical modifications I needed to make to this service for it satisfy all my security needs; however, due to its construct and scope, I couldn’t find a good way to extend it or to use a decorator pattern to utilize it. Instead, I chose to write my own authentication service. The code can be found below:
Next, I extended the ServiceAuthorizationManager class to provide the capability to validate users’ session and forms authentication cookies for web service calls. It ensures the user has authenticated, and that the identity in the session store matches the identity in the forms authentication token.
Finally, in the web.config file, I created two service behaviors. One for unauthenticated access to the login service (anonymousServiceBehavior), and one for authenticated access to all other web services (authenticatedServiceBehavior). Then in the service definition, I applied each of those behaviors using the behaviorConfiguration attribute.
The result is that all WCF calls to the IngredientsService and the ShoppingListService require authentication and ensure users forms authentication token is tightly coupled with the ASP.NET_SessionId.