Symfony 8.2 Nouveauté Publié le

Un lien dans une traduction, sans raw

Le filtre trans_html remplace les pseudo-balises d'une traduction par du HTML déclaré dans le gabarit, et échappe tout le reste, paramètres compris.

Notions abordées : TranslationTwigSécurité

Nouveau dans Symfony 8.2 (en développement). Pour traduire une phrase qui contient un lien, on mettait du vrai HTML dans le fichier de traduction, puis on l'affichait avec |raw. Trois défauts : l'adresse du lien est écrite en dur dans la traduction, un traducteur peut y glisser n'importe quel HTML, et raw coupe aussi l'échappement des paramètres. Si l'un d'eux vient de l'utilisateur, c'est une faille XSS.

Des pseudo-balises dans la traduction

La traduction ne contient plus que des balises sans attribut, que le gabarit transforme en HTML :

# translations/messages.fr.yaml
invitation: 'Bonjour %nom% ! <connexion>Connectez-vous</connexion> pour continuer.'
{{ 'invitation'|trans_html(tags: {
    connexion: { tag: 'a', attr: { href: path('connexion') } },
}, arguments: { '%nom%': nom }) }}
  • Une liste d'éléments les imbrique, du plus extérieur au plus intérieur : [{ tag: 'strong' }, { tag: 'a', attr: {…} }].
  • Seules les balises déclarées dans tags deviennent du HTML. Tout le reste est échappé : le texte, les paramètres, les valeurs d'attribut et toute balise non déclarée. Les éléments à contenu brut (script, style, iframe, noscript…) sont refusés.
  • Une traduction aux balises mal fermées est échappée en entier.
  • Le résultat est déjà sûr : pas de raw.

En PHP, par exemple pour un e-mail, le service Symfony\Component\Translation\HtmlTranslator fait la même chose.

À faire

La page d'accueil invite le visiteur à se connecter ou à créer un compte, en l'appelant par son prénom. L'aperçu s'ouvre sur /?prenom=<b>Ada</b> : le prénom s'affiche en gras, signe que le HTML saisi par le visiteur passe tel quel.

La boutique est traduite en français et en anglais. Passez l'invitation à trans_html : des pseudo-balises dans les deux traductions, des liens générés à partir des routes connexion et inscription dans le gabarit, et plus de raw. Mettez « créez un compte » en gras, en plus du lien.

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