Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bug #32455 [HttpFoundation] Clear invalid session cookie (Toflar)
This PR was submitted for the 4.2 branch but it was squashed and merged into the 4.3 branch instead (closes #32455). Discussion ---------- [HttpFoundation] Clear invalid session cookie | Q | A | ------------- | --- | Branch? | 4.2 (actually maybe should also go to 3.4, see below) | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | TODO | Fixed tickets | | License | MIT | Doc PR | not required Currently, invalid session cookies are not cleaned up. If the session is empty, the `AbstractSessionHandler::write()` destroys the session. If a new session has been started in the current process (meaning `session_start()` has sent the `Set-Cookie` header) then the `AbstractSessionHandler` will make sure this cookie is not sent to the client. If, however, `session_start()` did not send a cookie (meaning there was already a valid session ID in your request cookie), the `AbstractSessionHandler` will clear the session cookie (send a 0-lifetime cookie). If, however, the request does contain a session ID cookie but it is not valid, `session_start()` will send a new cookie which is then again cleared by the `AbstractSessionHandler`. But it will not clear the old cookie sent by the request. Here's a more complex example of what happens in the code flow when a user logs out and we regenerate a new session id for security reasons: 1. You have no `PHPSESSID` cookie yet. 2. You log into the system, you get a new `PHPSESSID` assigned. Let's go for session ID `1`. 3. You log out of the system, for security reasons you get session ID `2` regenerated. 4. The `AbstractSessionListener` pops in and calls `->save()` on your session handler. 5. The `NativeSessionStorage` calls the `StrictSessionHandler` (in fact the abstract parent, `AbstractSessionHandler`) which `write()`s the session data. In case the session data is empty, it will actually `destroy()` the session which means it will invalidate the session cookie. In that case, however, it won't send a 0-lifetime cookie because `$cookie = SessionUtils::popSessionCookie($this->sessionName, $sessionId);` will **not** return `null`. That is because after regeneration we actually do have a `Set-Cookie: PHPSESSID=2` header present. 6. This means, our `PHPSESSID=1` cookie is never deleted. Why is this a problem? Well, we have an invalid cookie that remains floating around forever. Loads of reverse proxies consider requests with cookies as being private and thus disable caching. I'm not sure this is the correct fix here but it felt like the only place we can do this because it has to happen during or after `$session->save()`. Looking for feedback first before we finish this with tests etc. Regarding Symfony 3.4: Not sure how this is affected because there's not even a `SessionUtils` class so I'd prefer to leave that fix to somebody who feels more comfortable with that code base 😄 /cc @aschempp Commits ------- b22a726 [HttpFoundation] Clear invalid session cookie
- Loading branch information