Symfony 8.2 New Published on

Asking for the password again before sensitive pages

IS_AUTHENTICATED_RECENTLY and IS_AUTHENTICATED_VERY_RECENTLY: a “sudo mode” that asks for the password again when the login is old.

Topics covered: Security

New in Symfony 8.2 (in development). IS_AUTHENTICATED_FULLY tells how the session started — with a password, not with a “remember me” cookie — but not when. A user who logged in this morning and leaves her computer open at lunch still passes the check. GitHub and others ask for the password again before sensitive actions: that's the “sudo mode” that Symfony 8.2 brings.

Two new attributes

#[IsGranted('IS_AUTHENTICATED_RECENTLY')]       // password given less than 2 h ago
#[IsGranted('IS_AUTHENTICATED_VERY_RECENTLY')]  // less than 5 min ago

They work wherever the other IS_AUTHENTICATED_* work: access_control, Twig, security expressions. On every interactive login, the token now records when the user proved their identity (here, by giving their password); a session opened by a “remember me” cookie has no such date, and therefore fails both.

The durations are set in security.yaml, in seconds:

security:
    recent_authentication_lifetime: 7200
    very_recent_authentication_lifetime: 300

Instead of a 403

By default, a failure gives a 403. To send the user back to enter their password again, you write a re-authentication entry point and declare it on the firewall:

final class ConfirmerIdentite implements ReAuthenticationEntryPointInterface
{
    public function startReAuthentication(Request $request, TokenInterface $token): Response
    {
        // …
    }
}
security:
    firewalls:
        main:
            re_authentication_entry_point: App\Security\ConfirmerIdentite

The firewall remembers the requested page before calling the entry point: once the password is given again, form_login brings the user back there.

Your task

Ada's customer area (ada / lovelace) opens everything to any session. Harden it:

  1. The invoices require a login less than one hour old.
  2. Changing the email address — which would allow resetting the password — requires a login less than ten minutes old.
  3. When the login is too old, ConfirmerIdentite redirects to /login, which then only asks for the password; after that, Ada comes back to the page she wanted.

The account home page, /account, stays open to any session.

Where the feature comes from: the original pull request.