forked from https://github.com/symfony/symfony
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
-------
|
||
---|---|---|
.composer | ||
.github | ||
src/Symfony | ||
.appveyor.yml | ||
.editorconfig | ||
.gitignore | ||
.php_cs.dist | ||
.travis.yml | ||
CHANGELOG-4.0.md | ||
CHANGELOG-4.1.md | ||
CHANGELOG-4.2.md | ||
CHANGELOG-4.3.md | ||
CODE_OF_CONDUCT.md | ||
composer.json | ||
CONTRIBUTING.md | ||
CONTRIBUTORS.md | ||
LICENSE | ||
link | ||
phpunit | ||
phpunit.xml.dist | ||
README.md | ||
UPGRADE-4.0.md | ||
UPGRADE-4.1.md | ||
UPGRADE-4.2.md | ||
UPGRADE-4.3.md | ||
UPGRADE-5.0.md |
Symfony is a PHP framework for web applications and a set of reusable PHP components. Symfony is used by thousands of web applications (including BlaBlaCar.com and Spotify.com) and most of the popular PHP projects (including Drupal and Magento).
Installation
- Install Symfony with Composer (see requirements details).
- Symfony follows the semantic versioning strictly, publishes "Long Term Support" (LTS) versions and has a release process that is predictable and business-friendly.
Documentation
- Read the Getting Started guide if you are new to Symfony.
- Try the Symfony Demo application to learn Symfony in practice.
- Master Symfony with the Guides and Tutorials, the Components docs and the Best Practices reference.
Community
- Join the Symfony Community and meet other members at the Symfony events.
- Get Symfony support on Stack Overflow, Slack, IRC, etc.
- Follow us on GitHub, Twitter and Facebook.
- Read our Code of Conduct and meet the CARE Team
Contributing
Symfony is an Open Source, community-driven project with thousands of contributors. Join them contributing code or contributing documentation.
Security Issues
If you discover a security vulnerability within Symfony, please follow our disclosure procedure.
About Us
Symfony development is sponsored by SensioLabs, led by the Symfony Core Team and supported by Symfony contributors.