Nouveau dans Symfony 8.2 (en développement). Un lien de connexion (login_link) connecte sans mot de passe : il porte l'identifiant, une date d'expiration et une signature. Tout ce qu'on y ajoutait ensuite — la page où ramener le lecteur, typiquement — restait hors signature. N'importe qui pouvait donc le changer, et faire d'un vrai lien, envoyé par vous, une redirection vers un autre site.
Des paramètres signés
createLoginLink() accepte désormais des paramètres, que la signature couvre :
$lien = $liens->createLoginLink($utilisateur, $request, null, ['return_to' => '/compte/factures']);
Changez ou retirez l'un d'eux, et le lien ne connecte plus personne. À l'arrivée, les paramètres vérifiés attendent dans un attribut de la requête :
$retour = $request->attributes->get('_login_link_parameters')['return_to'] ?? null;
Lisez-les là, pas dans la query string : un paramètre ajouté après coup — un traceur de messagerie, ou pire — y apparaît sans avoir été signé. Symfony l'ignore ; votre code doit en faire autant.
La signature prouve que return_to vient de vous, pas qu'il mène chez vous : quiconque peut demander un lien peut aussi demander un lien signé vers un autre site. N'y acceptez donc qu'un chemin du site.
À faire
LienController fabrique le lien qui partirait par mail (la réponse le montre) et y colle return_to à la main ; RedirectionApresLien le relit dans la query string. Le lien est authentique, sa destination non : remplacez /compte/factures par un autre site, et le lecteur s'y retrouve, connecté.
- Faites signer
return_topar le lien. - Dans
RedirectionApresLien, ne lisez plus que les paramètres signés. - N'y suivez qu'un chemin du site (
/…, mais pas//…) ; sinon, menez à/compte.