Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session locking pitfall #24875

Closed
enumag opened this issue Nov 9, 2017 · 9 comments
Closed

Session locking pitfall #24875

enumag opened this issue Nov 9, 2017 · 9 comments

Comments

@enumag
Copy link
Contributor

enumag commented Nov 9, 2017

Q A
Bug report? no
Feature request? yes
BC Break report? no
RFC? no
Symfony version 3.3

Recently we found an issue in our Symfony application that certain ajax requests (that could take a long time) caused the application to be unresponsive until they were completed. The problem was that the ajax request locked the session and other requests were waiting for that.

Once we found the cause it was of course easy to fix by calling $session->save(); manually before doing the main work (which did not require session). Finding the cause in the first place took a long time though.

The reason why I'm wring this issue is that I'd like to have some configuration that would prevent this issue in the first place - it's a pitfall that is easy to fall into even for experienced symfony users. When writing an IS the user needs to log in first and then you obviously need to read the session to check his permissions on every request. However most requests don't really need to do anything else with the session so it's useless to keep it open and locked after reading the user information. Why is the session even locked when I only need to read? What I'd like to achieve is a state where the session is automatically closed as soon as possible unless the current controller action is whitelisted as one that needs to work with session. It might be nice to have such behaviour as default in Symfony 5.

Of course if you have some other good-practice solution, please share.

@Simperfit
Copy link
Contributor

Status: Needs Review

@aaa2000
Copy link
Contributor

aaa2000 commented Nov 10, 2017

I recently encountered the same problem and I created an issue to document it symfony/symfony-docs#8586

You could create a listener that auto-closes session on ajax requests like mentionning in the article
https://tideways.io/profiler/blog/slow-ajax-requests-in-your-symfony-application-apply-this-simple-fix

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Nov 19, 2017

Why is the session even locked when I only need to read

the issue here is that this is easily said, but almost impossible to know at runtime: the session engine cannot know that you're only going to read its values. There could be a way to make it aware of that, but that could only be done by you (userland) telling it so in some way that doesn't exist yet and has to be invented.

@gsdevme
Copy link
Contributor

gsdevme commented May 1, 2018

I've also experienced this and agree with @nicolas-grekas this is a userland problem.

One way to combat this to make sure your firewall its very well defined so rather than having prefix: ^/ as your prefix for sessions have a narrow prefix for session writing (lets says ^/account then have a public firewall which is security:false preventing any access to sessions read or write.

Once you have this you then need to implement a time based token you can use for the sake of reading only. (you could also use hmac's to validate you created it i.e. public/private key)

You load a /account page which is inside the firewall and create a token which expires within 300 seconds (lets say) and via the DOM bootstrap it into React/JQuery (whatever is used for async requests). Then you can make /api/account/customer/1337 request with the token that allows for 'authentication' via the token without needing to read/write to session.

Any endpoints that don't require a session in general shouldn't be within the firewall and therefore won't cause session locking by symfony auto booting the session due to firewall rules.

@fabpot
Copy link
Member

fabpot commented Aug 6, 2019

Closing as there is nothing we can do in Symfony itself.

@fabpot fabpot closed this as completed Aug 6, 2019
@d42ohpaz
Copy link

@nicolas-grekas @fabpot:

the issue here is that this is easily said, but almost impossible to know at runtime: the session engine cannot know that you're only going to read its values. There could be a way to make it aware of that, but that could only be done by you (userland) telling it so in some way that doesn't exist yet and has to be invented.

Closing as there is nothing we can do in Symfony itself.

PHP 7 supports passing ['read_and_close' => true] to session start, which effectively creates read-only sessions. Unfortunately, the session handlers in Symfony do not support this flag in any capacity. But, it can be managed by Symfony.

@florianajir
Copy link

According to @9ae8sdf76 comment this issue could be requalified ?

@Tobion
Copy link
Contributor

Tobion commented Oct 19, 2019

please open a new issue with a detailed description

@mevdschee
Copy link

PHP 7 supports passing ['read_and_close' => true] to session start, which effectively creates read-only sessions.

This option is not really suitable for read-only sessions as the session timestamp is not updated that way. I believe your best option is to call session_write_close after session_start.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests