-
Notifications
You must be signed in to change notification settings - Fork 824
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
Remember Me functionality fails when renewal is interrupted #11281
Comments
Can confirm both from the actual src code and the tests of the laravel implementation that they don't cycle the token except to set it during initial login (and if it's missing) and to remove it when logging out. I'd say that's the way to go. It does look like Syfony cycles it (if it hadn't already been cycled in the last minute): So I'm not sure if they have similar issues to what this issue describes. |
That does depend on whether they have a reliable attack method that they can repeat, or if it's once-off. If it's once-off, then cycling Given Laravel doesn't bother with it I'm inclined to accept that it's not doing a lot of good, but I'd like other opinions from @silverstripe/core-team if anyone has one. |
@Cheddam if no one replies in say a week or so, feel free to raise a PR and we can proceed from there. |
Removing the recycling of these would result in many more entries in the I'm not sure I really see the use case for removing the existing functionality myself - sounds like this was a transient network issue that caused a request to be sent and processed but the HTTP response was not received by the browser so they never found out about the new Agree that the rotation itself doesn't really achieve very much - as long as you're running over HTTPS you should be pretty safe from attack and/or the |
With Option 1, there'd still only be one There's a range of potential triggers for the response not getting to the browser - a user double-clicking a link, multiple tabs of the same site rehydrating when a user reopens their browser, a user going through a tunnel and spamming refresh, a SPA firing off multiple asynchronous API requests to update the UI (this one may not trigger a full logout as the new value would still reach the browser, but could still trigger a failure in other requests sent before the new cookies arrived.) One more wrinkle that we'd need to account for in Option 2 is if multiple requests resolve and successfully relay new cookies to the browser, but the responses are out of order, resulting in now-outdated cookies being set. (I really think Option 1 is going to be the best path forward.) |
I'm working on a patch based on Option 1, making this configurable and retaining the current behaviour by default. My gut feeling is that structuring it as configuration constitutes a minor change rather than a patch, but happy to be convinced otherwise - any thoughts @GuySartorelli? |
Yup, new configuration properties are new public API, so should be included in a minor release. |
It's not likely anyone will ever bother applying the change in their projects though - so if we think that the new behaviour is better, we should probably have it be the behaviour in CMS 6. |
Resolves silverstripe#11281. Renewing the token/hash during an active session can trigger a logout in the event of request failures or simultaneous requests. This also marks the renew method as deprecated, to be removed entirely in 6.0.
Resolves silverstripe#11281. Renewing the token/hash during an active session can trigger a logout in the event of request failures or simultaneous requests. This also marks the renew method as deprecated, to be removed entirely in 6.0.
@GuySartorelli Regarding an open question from the merged PR - the Session Manager module depends on the I'll work on getting a PR up for the 6 branch to fully drop the renewal logic soon - let me know what you think about shifting / replacing the |
But it only does that on renewal, right? It has a separate extension hook for on generation. If it's meant to happen on every authentication, then a Basically, when you do the PR, if an extension hook is needed and an existing one doesn't fit the purpose, just add one with an appropriate name in the appropriate place. tl;dr I'm sure whatever you do in the PR will be good code 👍 |
@Cheddam Are you still intending on raising a CMS 6 PR for this? |
@GuySartorelli Yep! Should have it ready for you to look at next week. |
Module version(s) affected
Tested against 5.2.x but related logic introduced in 4.x
Description
The 'Remember Me' feature stores two additional cookies in the user's browser that enable Silverstripe CMS to renew the user's session when it is destroyed (either through a timeout on the server side or when the user closes/reopens their browser.)
The
alc_device
cookie is static throughout the lifetime of the login, but thealc_enc
cookie value is rotated whenever the session is renewed. This makes some sense from a security perspective, in the same vein as CSRF token rotation, but it relies on the browser receiving the new value, which is not guaranteed - network issues or user behaviour could result in a failure or cancellation of the request prior to headers being returned to the browser.In any case where the browser does not receive the new cookie value, any subsequent request will transmit the original, which no longer maps to an active
RememberLoginHash
, triggering a logout.How to reproduce
PHPSESSID
/SECSESSID
cookie to simulate expiry of the session (or wait for it to time out)sleep(10)
in the relevant controller method to simulate this)Possible Solution
I see two potential avenues to resolution:
Option 1: Remove/disable rotation logic
As previously mentioned, the rotation does make some sense from a security standpoint, but the risk it mitigates is arguably minimal. If an attacker can steal the
alc_enc
cookie, they can also steal theSECSESSID
cookie, and they will likely exploit it while it is fresh regardless.Based on this, either removing the rotation step entirely, or allowing it to be disabled in configuration, seems like a viable solution. To be clear, this should only affect rotation during the lifetime of a login - explicit logouts and new logins should still generate a fresh value.
For a quick comparison, I took a look at Laravel's equivalent implementation and it appears that they do not perform rotation of the token during the lifetime of the login.
Option 2: Introduce a grace period
This would be more complex to implement / maintain, and the exact parameters would need to be considered, but in essence we could mitigate this failure by respecting requests with a stale
alc_enc
within a small window and re-transmitting the renewed value.Additional Context
No response
Validations
silverstripe/installer
(with any code examples you've provided)PRs
The text was updated successfully, but these errors were encountered: