SECURITY: Allow extensions to supress the reauth flag on login

CVE-2025-6926

This is a workaround for extensions with some sort of "autologin"
implemented via the login page to indicate that the login flow
didn't involve the user actually logging in, it merely copied
some central login state, and so isn't appropriate for the
reauthentication flag.

This isn't the best way to provide an interface to extensions
(if we keep it, a more explicit interface, such as a
SessionPropertiesAuthenticationRequest object that's part of
the initial request set and can be modified by providers,
and can also be used for the "remember me" flag, would be
nicer), and maybe the whole approach of letting extensions
suppress the reauthentication flag is not the best way of
handling the problem in the first place, but it's simple
which is important for a security patch.

Bug: T389010
Change-Id: Ifce73837b25b0caad2d3d3cba000cceb0184c29d
This commit is contained in:
Gergő Tisza 2025-06-15 16:00:05 +02:00 committed by Reedy
parent 3340302f40
commit b1adf3c728

View file

@ -187,6 +187,15 @@ class AuthManager implements LoggerAwareInterface {
*/
public const REMEMBER_ME = 'rememberMe';
/**
* @internal To be used by primary authentication providers only.
* @var string Primary providers can set this to false after login to prevent the
* login from being considered user interaction. This is important for some security
* features which generally interpret a recent login as proof of account ownership
* (vs. a stolen session).
*/
public const LOGIN_WAS_INTERACTIVE = 'loginWasInteractive';
/** Call pre-authentication providers */
private const CALL_PRE = 1;
@ -918,7 +927,8 @@ class AuthManager implements LoggerAwareInterface {
$rememberMe = ( $req && $req->rememberMe ) ||
$this->getAuthenticationSessionData( self::REMEMBER_ME );
}
$this->setSessionDataForUser( $user, $rememberMe );
$loginWasInteractive = $this->getAuthenticationSessionData( self::LOGIN_WAS_INTERACTIVE, true );
$this->setSessionDataForUser( $user, $rememberMe, $loginWasInteractive );
$this->callMethodOnProviders( self::CALL_ALL, 'postAuthentication', [ $user, $response ] );
$performer = $session->getUser();
$session->remove( self::AUTHN_STATE );