QiuYucheng2003 opened a new issue, #2473: URL: https://github.com/apache/shiro/issues/2473
### Search before asking - [x] I had searched in the [issues, **including closed issues**](https://github.com/apache/shiro/issues?q=is%3Aissue) and found no similar issues. ### Environment JDK 8 MacOS 13.0 ### Shiro version main ### What was the actual outcome? The ThreadContext class uses a static final ThreadLocal<Map<Object, Object>> RESOURCES (Line 63) to store security contexts. This design lacks an automated cleanup mechanism. If the caller (e.g., a Filter or Interceptor) fails to strictly execute ThreadContext.remove() (e.g., due to an unchecked exception disrupting the flow before the finally block), the security context (Subject/Identity) remains bound to the thread. In a thread-pool environment (common in Web Containers), this leads to Context Contamination: a subsequent request reusing the same "dirty" thread may inherit the previous user's identity and privileges, resulting in potential Privilege Escalation. ### What was the expected outcome? The framework should ensure that ThreadLocal resources are reliably cleaned up at the end of the request lifecycle, regardless of execution outcome. Ideally, ThreadContext should guard against stale data reuse, or the framework should enforce a safer lifecycle management mechanism to prevent identity leaks across thread boundaries. ### How to reproduce This is a logic flaw identified via Static Analysis (Unrefactored ThreadLocal pattern): 1. Setup: Use a Web Container with a fixed thread pool. 2. Step 1: Request A (Admin) calls ThreadContext.bind(adminSubject). 3. Step 2: Simulate an exception or logic error that causes the request to terminate without triggering ThreadContext.remove(). 4. Step 3: The thread returns to the pool with RESOURCES still populated. 5. Step 4: Request B (Anonymous) is processed by the same thread. 6. Step 5: Calls to ThreadContext.getSubject() in Request B return Request A's Admin Subject, bypassing authentication. ### Debug logs Location: org.apache.shiro.util.ThreadContext.java // Line 63: Static ThreadLocal with life-long duration private static final ThreadLocal<Map<Object, Object>> RESOURCES = new ThreadLocal<>(); // Methods like put() and bind() populate this map but do not guarantee removal. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
