Code PHP / Twig — vulnérabilité Symfony CVE-2026-46640
News

CVE-2026-46640 : exécution de code PHP arbitraire dans Twig contourne le sandbox Symfony

Twig publie un correctif urgent pour CVE-2026-46640, une exécution de code PHP arbitraire qui contourne intégralement le sandbox Symfony. Six avis publiés…
Sara Amin
Marketing Student • Content & Writing Enthusiast

Un template suffit. Le 20 mai 2026, Twig a livré une faille qui transforme une simple chaîne entre parenthèses en exécution PHP arbitraire, et qui ignore complètement le sandbox censé contenir ce genre d'abus. CVE-2026-46640 vise les applications où un utilisateur peut influencer le code source d'un template, ce qui couvre une bonne partie des CMS multi-tenants, des plateformes no-code et des SaaS personnalisables construits sur Symfony.

Ce qui s'est passé

L'équipe Symfony a publié six avis de sécurité simultanément le 20 mai 2026. Une salve inhabituelle par son volume et par la gravité de la pièce maîtresse. La vulnérabilité la plus critique, CVE-2026-46640, concerne le moteur de templates Twig dans toutes les versions à partir de 3.15.0 jusqu'à 3.25.x incluse. Elle a été découverte par Claude Mythos Preview dans le cadre du projet Glasswing, un effort d'audit assisté qui cible spécifiquement les chemins de compilation des moteurs de templates PHP.

Le correctif est consolidé dans Twig 3.26.0. Côté Symfony, les versions à déployer sont 5.4.52, 6.4.40, 7.4.12 et 8.0.12. La page d'index des avis regroupe l'ensemble des publications de la journée, et c'est probablement le point d'entrée le plus efficace pour les équipes qui doivent rendre compte rapidement à un comité de sécurité.

Le mécanisme technique

Twig 3.15.0 avait introduit une nouvelle syntaxe d'accès dynamique aux attributs, obj.(expr), pour remplacer la fonction attribute() dépréciée. L'idée est légitime: permettre de calculer le nom d'une propriété à l'exécution sans recourir à un appel de fonction. Le problème se loge dans le DotExpressionParser, qui prend une mauvaise décision lorsque deux conditions se conjuguent: le récepteur est _self ou un alias d'import, et l'expression entre parenthèses est une chaîne littérale.

Dans ce cas précis, le parser ne génère pas un accès d'attribut. Il route l'expression vers le chemin d'appel de macro et construit un MacroReferenceExpression en concaténant directement la chaîne contrôlée par l'attaquant, sans validation d'identifiant. Quand le compilateur Twig appelle ensuite MacroReferenceExpression::compile(), ce nom est émis tel quel dans le code PHP généré. Une chaîne comme '); system($_GET["c"]); // sort donc directement dans le fichier PHP compilé du template. À l'instant où le template est chargé, PHP exécute ce code.

Le détail qui fait basculer la gravité, c'est que tout cela se passe au moment de la compilation, pas à l'exécution du rendu. Le sandbox Twig, lui, intervient via checkSecurity() au moment du rendu. L'attaquant a déjà gagné avant que le moindre contrôle de politique de sécurité ne soit appelé.

Pourquoi le contournement du sandbox compte

Beaucoup d'équipes ont construit leur modèle de menace autour d'une hypothèse rassurante: activer SandboxExtension, même avec une SecurityPolicy vide, empêcherait un template hostile de causer des dégâts. Cette hypothèse ne tient plus. CVE-2026-46640 contourne le sandbox dans toutes ses configurations, y compris en mode global. Le code PHP s'exécute pendant la compilation du template, c'est-à-dire avant l'évaluation de la politique de sécurité.

Les victimes types sont identifiables sans ambiguïté. Tout produit qui permet à un client final, à un opérateur de tenant, à un utilisateur d'une marketplace de thèmes, ou à un plugin tiers, de fournir du source Twig est exposé. Cela inclut une partie significative de l'écosystème Drupal, eZ Platform, ainsi que des SaaS français et européens construits sur Symfony qui offrent de la personnalisation de templates d'email, de pages de portail ou de notifications. Si vous avez un doute sur votre surface d'attaque réelle, le bon réflexe est de chercher où, dans votre code, un Twig\Loader\ArrayLoader ou un ChainLoader consomme une entrée externe.

Sur une application Symfony standard où seuls les développeurs poussent des templates via Git, le risque direct est faible. Sur une plateforme multi-tenants qui laisse un administrateur de tenant définir ses propres gabarits, il est immédiat et critique. Cette distinction est exactement celle qu'on utilise pour prioriser les CVE qui comptent dans un backlog de remédiation: la criticité CVSS ne dit rien tant qu'on n'a pas mappé la condition d'exploitation à une fonctionnalité réelle du produit.

Les autres CVE de la même salve

La deuxième vulnérabilité Twig, CVE-2026-24425, concerne un contournement de sandbox lors de l'utilisation d'une source policy. Elle touche Twig 2.16.* et les versions 3.9.0 jusqu'à 3.25.x. Le correctif est également dans Twig 3.26.0, ce qui rend la mise à jour vers cette version doublement utile. Moins spectaculaire que CVE-2026-46640, mais elle vise les configurations qui pensaient s'être protégées par une politique de source, donc précisément les équipes les plus matures sur le sujet.

CVE-2026-46626 est d'une nature différente. C'est un contournement du patch publié pour CVE-2024-50340 dans SymfonyRuntime, exploitable via une discordance entre parse_str et l'argv exposé par la SAPI. Les versions affectées couvrent 5.4.46 à 5.4.51, 6.4.14 à 6.4.39, 7.1.7 à 7.4.11, et 8.0 à 8.0.11. Ce type de régression de patch est désagréable parce qu'il invalide la confiance accordée à une remédiation antérieure.

Le reste de la salve englobe une usurpation d'identité via X509Authenticator, des problèmes dans HtmlSanitizer, un bypass de route-requirement dans UrlGenerator, et de l'injection d'en-tête email et de commande SMTP dans Symfony\Component\Mime\Address. Aucune n'atteint le niveau de CVE-2026-46640, mais l'injection SMTP mérite une attention particulière sur les applications qui acceptent des adresses email d'utilisateurs non authentifiés.

Que faire maintenant

L'ordre est simple. D'abord, passer Twig à 3.26.0 partout. Cette mise à jour seule résout les deux CVE Twig publiées le même jour, et elle est compatible en API avec les 3.x antérieures. Ensuite, aligner Symfony sur 5.4.52, 6.4.40, 7.4.12 ou 8.0.12 selon votre branche. Si vous ne pouvez pas pousser les deux en même temps, Twig passe en premier parce que c'est la faille qui donne du RCE non authentifié dans les pires scénarios.

Côté vérification, composer show twig/twig et composer show symfony/symfony donnent l'état réel des versions installées. Attention aux applications qui figent les versions via composer.lock sans audit régulier: une partie du parc va découvrir qu'elle est restée en 3.20 alors que les équipes pensaient être à jour. Les IOC pertinents à surveiller dans les logs sont les requêtes contenant des chaînes Twig avec _self.( suivi d'une chaîne, ainsi que toute trace inhabituelle de compilation de template provenant d'entrées utilisateur. Les fichiers générés dans le cache Twig sont aussi à inspecter sur les environnements à risque.

Pour les équipes qui n'ont pas encore industrialisé la veille sur ce type d'événement, c'est un cas d'usage idéal pour évaluer une solution de threat intelligence: six avis simultanés, des dépendances transitives partout, et une fenêtre d'exploitation potentiellement courte avant que des PoC publics ne circulent.

Questions fréquentes

Mon application Symfony est-elle exploitable si les utilisateurs ne peuvent pas écrire de templates ?

Dans le cas standard, où seuls les développeurs poussent du Twig via le dépôt Git, l'exposition directe à CVE-2026-46640 est nulle. La condition d'exploitation exige que l'attaquant fournisse du source de template, ce qui n'est pas votre situation. Restent les chemins indirects: un plugin tiers qui accepte du Twig dans sa configuration, un éditeur de notifications email côté admin, ou un import de thème depuis une archive. Vérifiez aussi que vous n'utilisez pas Twig\Loader\ArrayLoader avec une chaîne dérivée d'une requête HTTP, même indirectement.

Le sandbox Twig ne suffit-il pas à se protéger ?

Le sandbox a été conçu pour contenir l'exécution d'un template au moment du rendu. CVE-2026-46640 s'exécute avant ce point, pendant la compilation du template en code PHP. Concrètement, l'attaquant n'a même pas besoin que son template soit jamais rendu: il suffit qu'il soit chargé par Twig. Toutes les configurations de sandbox sont contournées, y compris celles avec une SecurityPolicy vide en mode global. C'est ce qui fait basculer cette CVE de "ennuyeuse" à "critique".

Faut-il mettre à jour en urgence ?

Imaginez le scénario: un client de votre plateforme SaaS crée un template d'email personnalisé, insère la charge utile, et obtient un shell PHP sur votre serveur applicatif. Ce scénario n'est pas théorique pour une partie du marché. Si votre produit autorise une forme quelconque de template utilisateur, la mise à jour est à traiter dans la journée. Si votre application est purement développeur-only, vous pouvez intégrer la mise à jour dans votre prochain cycle de release, mais sans la repousser au-delà d'une à deux semaines, parce que la régression du patch dans CVE-2026-46626 montre que les chaînes de dépendances Symfony méritent d'être tenues à jour de manière disciplinée.

About the author
Sara is a marketing student and tech writing enthusiast with an interest in digital culture, startups, and emerging technologies.

Related Articles

Discover simplified
Cyber Risk Management
Request access and learn how we can help you prevent cyberattacks proactively.