Symfony 8.2 Nouveauté Publié le

Changer de secret sans casser les liens déjà envoyés

Le secret de framework.uri_signer accepte une liste : le premier signe les nouveaux liens, tous vérifient ceux qui circulent encore.

Notions abordées : HttpFoundationSécurité

Nouveau dans Symfony 8.2 (en développement). Les URL signées, les liens de connexion, les cookies « se souvenir de moi » et les messages Messenger signés reposent tous sur un secret. Le changer, après une fuite ou par simple hygiène, cassait d'un coup tout ce qu'il avait signé : les liens déjà envoyés par mail cessaient de marcher.

Une liste de secrets

Chaque fonction qui signe a maintenant son option secret, qui accepte une liste. Le premier signe, tous vérifient ; chacune vaut kernel.secret par défaut.

# config/packages/framework.yaml
framework:
    uri_signer:
        secret: ['%env(URI_SIGNER_SECRET)%', '%kernel.secret%']

    messenger:
        serializer:
            signing_secret: ['%env(MESSENGER_SIGNING_SECRET)%', '%kernel.secret%']
# config/packages/security.yaml
security:
    firewalls:
        main:
            remember_me:
                secret: ['%env(REMEMBER_ME_SECRET)%', '%kernel.secret%']

On retire l'ancien secret quand plus rien de ce qu'il a signé ne sert : une fois expirés les liens envoyés avec lui. Les messages Messenger sont signés à nouveau à chaque nouvel essai, et les cookies « se souvenir de moi » à chaque connexion : ils passent d'eux-mêmes au nouveau secret.

Symfony 8.2 ajoute aussi sign: true sur un transport Messenger : tous ses messages sont signés, et un message mal signé est refusé avant même d'être lu.

À faire

Le 24 octobre, l'équipe a remplacé le secret qui signe les invitations : URI_SIGNER_SECRET contient le nouveau, URI_SIGNER_ANCIEN_SECRET l'ancien (voir config/packages/secrets.yaml). Depuis, toutes les invitations envoyées avant répondent 404.

  1. Les invitations déjà envoyées doivent fonctionner jusqu'à leur expiration, et les nouvelles être signées avec le nouveau secret.
  2. Le contrôleur signe sans expiration, ce que Symfony 8.2 déprécie : donnez aux liens une expiration par défaut de sept jours, dans la configuration.

D'où vient la fonctionnalité : la pull request d'origine.