Today, we're going to discuss a simple bug that marked the beginning of my learning journey. It may seem basic now, but for someone from a humble background who had never even touched a computer, it was a significant challenge. Looking back, it might not seem like much, but it holds a special place in my heart as the starting point of my growth.
In the early days, we used the Common ClassLoader (tomcat/lib) for all web applications (contexts). Let's assume we had two contexts named app1 and app2—both applications' JAR files were placed in the common class loader, allowing them to access each other's classes. From a security perspective, this approach was not ideal. To address this, we switched to using the WebApp ClassLoader (tomcat/webapps/app1/WEB-INF/lib/), ensuring isolation between applications.
We maintain a HashMap that stores user details against a unique ID retrieved from cookies. If no entry exists for the given ID, we check the database to see if there are any records associated with it. If found, we repopulate the HashMap. When a user logs out, we remove their entry from both the HashMap and the database.
In the common class loader setup, when a user logs out from app1, their entry is removed from both the common HashMap and the database. Since app2 shares the same class loader, the user's session is also cleared there, effectively logging them out from app2 as well.
However, after moving to the WebApp ClassLoader model, when a user logs out from app1, we clear their cache entry from app1's HashMap and remove the corresponding database entry. But since app2 maintains its own separate HashMap, the cache still exists there. As a result, the user can continue accessing app2 using the unique ID from the cookie, even though the database entry has been invalidated.
Instead of mitigating the security threat, we ended up creating a SEVERE security vulnerability. While trying to isolate applications using the WebApp ClassLoader, the session cache in App2 remained intact even after a user logged out from App1. As a result, the user could still access App2, despite their session being invalidated in the database.
As a solution, we migrated the HashMap from JVM cache to Redis cache. This ensured a centralized session store, allowing consistent session management across applications and preventing unauthorized access after logout.




Comments
Post a Comment