SessionProvider::provideSessionInfo() returns null if the session credentials are invalid. But it also returns null if there are no session credentials at all. So there is no way to signal "session credentials are invalid and should be cleared" (ie. SessionManager should unpersist the session).
This hasn't come up before, because 1) when provideSessionInfo() does return a session and it is found invalid during the store check (SessionManager::loadSessionInfoFromStore()), SessionManager does unpersist, and that's usually how it goes for cookie-based sessions; 2) most immutable session providers cannot persist / unpersist anyway, 3) when provideSessionInfo() returns null, we end up with an empty session, and usually CookieSessionProvider (or its CentralAuth version) will be called to provide an empty session, which is basically the same as unpersisting (it will delete the session cookies it knows about).
But BotPasswordSessionProvider does persist/unpersist, and cannot handle empty sessions so that will be done by CookieSessionProvider, meaning when something (such as the session JWT added in T415007) is invalid and BotPasswordSessionProvider::provideSessionInfo() returns null, the <wiki>_BPsession cookie won't get cleared.
Steps to reproduce:
- enable JWT cookies for bot password sessions
- set up a bot password and log into it
- modify the JWT to e.g. contain an invalid issuer
- send an API request
Expected: request is seen as anonymous, sessionJWT and <wiki>_BPsession cookies get deleted
Actual: request is seen as anonymous, sessionJWT cookie gets deleted but <wiki>_BPsession cookie doesn't (so the next request will not be anonymous)