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
tagsdeviennent 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.