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

Sessions may never expire: make Renewal Timeout opt-in, implement Absolute Timeout #553

Closed
Slamdunk opened this issue Dec 23, 2022 · 6 comments · Fixed by #554
Closed

Sessions may never expire: make Renewal Timeout opt-in, implement Absolute Timeout #553

Slamdunk opened this issue Dec 23, 2022 · 6 comments · Fixed by #554

Comments

@Slamdunk
Copy link
Member

There are 3 Automatic Session Expiration mechanism this library should provide:

  1. Idle Timeout: after a period of inactivity, a session must expire. That's already implemented
  2. Renewal Timeout: if you keep working actively, your session gets renewed. That's already implemented, but be completely disabled only partially
  3. Absolute Timeout: no matter what, the session must expire after a defined time window. That's missing

Issue 1/3: Renewal Timeout is a hidden behaviour

Currently both README.md and docs/configuration.md lack of a proper explanation of what's going on under the hood, which is that by default the session is potentially infinite if the user keeps interacting with the application and the configured $expirationTime is greater than $refreshTime, and that's highly likely given that the default $refreshTime is 60 seconds.

This is even worse at a communication level considering that it deeply differs from the default ext-session behaviour; I bet most consumer of this library expect just replacement of code, not of timeout mechanisms.

Solution: write a better documentation

Issue 2/3: Renewal Timeout should be opt-in

Renewal Timeout mechanism it's not recommended to be a default.
Re-authentication should occur if not explicitly configured otherwise.

I'm using the undocumented workaround of setting $refreshTime = 1 + $expirationTime to disable it, if anyone wonders how to opt-out in current major release.

Solution: disable the default Renewal Timeout, make it opt-in. BC break

Issue 3/3: Absolute Timeout is unachievable

Even when the Refresh Timeout is disabled with the $refreshTime = 1 + $expirationTime trick, the session gets renewed if the content changes, and the Timeout shifts afar again because the expiration time always starts from $this->clock->now():

if ($sessionContainerChanged || $this->shouldTokenBeRefreshed($token)) {
return FigResponseCookies::set($response, $this->getTokenCookie($sessionContainer));
}

$now = $this->clock->now();
$expiresAt = $now->add(new DateInterval(sprintf('PT%sS', $this->expirationTime)));

Solution: when Renewal Timeout is disabled, inherit $expiresAt value from current Session token. BC break


Ping @malukenho and @lcobucci for feedbacks, you've worked on this in 89719b3 and #14

I'll propose a PR once you've reviewed this issue.

@Ocramius
Copy link
Member

if the user keeps interacting with the application

This is pretty much what all session systems do?

Re-authentication should occur if not explicitly configured otherwise.

Disagree here too: session stays hot while being used 🤔
If there is a concept of "locking the user out" while navigating the application, that is added security theatre that shouldn't be done here, IMO.

Absolute Timeout is unachievable

I didn't understand this part.

@Slamdunk
Copy link
Member Author

Slamdunk commented Dec 23, 2022

I didn't understand this part.

Our company and customers policy mandates that every 12 hours each user must re-authenticate and re-authorised for any work to be done.
Each day many users change functions, and some are fired.

That's what Absolute Timeouts are for: I don't care if your are active or not, I don't care if you are interacting with the app or not, after 12 hours you must re-login.

The $expiresAt = $this->clock->now()->[...] prohibits me to adhere to the policy, as I don't have the control over the exact expiration time.

An advanced user may just throw a script that keeps refreshing its session every 30 seconds.
He walks off from the computer, after 10 years he comes back and the newly refreshed session token is still valid, even though the last re-auth has been done over a decade ago.

@Ocramius
Copy link
Member

Our company and customers policy mandates that every 12 hours each user must re-authenticate and re-authorised for any work to be done.

I'd say that this is domain-specific logic then, and shouldn't be part of this lower-level infrastructural layer. What you are looking for is something akin to the Laminas\Session\Container stuff from "the olden time", which:

  • were based on the underlying session
  • had "steps" and "time" expiries

@Ocramius
Copy link
Member

What I'm arguing here is that the underlying storage is mostly tracking the session storage: things like "you must tap your feet 3 times at the 3rd day, then wait for the planets to align and sing the song of time" should be at a higher level :D

@Slamdunk
Copy link
Member Author

Slamdunk commented Dec 23, 2022

should be at a higher level

I partially disagree on this: binding high level requirements to low level bonds is efficient and effective.

But understand your argument and accept the reason for marking issues 2 and 3 as invalid

I'll open a PR for issue 1 though.

@Ocramius
Copy link
Member

Closing as per #554

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

Successfully merging a pull request may close this issue.

2 participants