Mythos a audité Symfony. Voilà ce que ça donne vraiment.
Temps de lecture estimé : 10 minutes
C'est lors de l'AFUP Days 2026 de Lyon qu'Alexandre Daubois, membre de la core team Symfony, a ouvert une parenthèse sur le sujet pendant son talk. Comme vous pouvez l'imaginer, cette information a fortement aiguisé mon intérêt, et j'ai donc voulu commencer à creuser.
Il faut que je sois honnête sur ce que j'avais en tête en commençant. Depuis le lancement de Claude Mythos, j'ai des réserves sur l'outil. Pas sur la capacité technique d'Anthropic, mais sur ce que les résultats vont produire concrètement dans la vraie vie d'une équipe de développeurs ou de sécurité.
Alors forcement, quand je tombe sur un audit qui porte sur Symfony, un framework que je connais bien. C'était l'occasion parfaite de vérifier mes intuitions.
Commençons par les faits : le 21 mai 2026, le blog officiel de Symfony annonce qu'Anthropic a soumis Symfony à Claude Mythos Preview via le Project Glasswing. La core team a reçu un ZIP contenant 19 rapports de vulnérabilité, les a relus manuellement, et les 19 étaient réelles. Zéro faux positif. Impréssionnant !
Mais deux questions me dérangent d'emblée.
Côté Anthropic : qu'est-ce qu'il y avait dans les findings bruts avant que ce ZIP soit constitué ? Combien de rapports Mythos a-t-il produit en tout, et sur quels critères ces 19 ont-elles été sélectionnées ?
Côté CVE : est-ce que ces vulnérabilités sont réellement exploitables, ou les conditions d'exploitation sont-elles si spécifiques qu'elles ne concernent presque personne en prod ?
C'est ainsi que j'ai parcouru les security advisories de Symfony pour retrouver les CVE associées à Glasswing. J'en ai trouvé 17 où Mythos est explicitement cité.
Ce sont elles que j'ai décidé d'analyser pour essayer de répondre à ces questions.
Le score de sévérité ne vous dit pas si vous êtes concerné
Quand une CVE sort, le réflexe naturel est de regarder le score CVSS (Critical, High, Medium, Low). Et on priorise dans cet ordre.
Le problème, c'est que le CVSS pondère avant tout l'impact d'une exploitation réussie, pas la probabilité qu'elle se produise dans votre app, dans votre contexte. Une RCE (Remote Code Execution, exécution de code arbitraire sur le serveur) avec un score Critical peut ne jamais toucher un seul serveur en prod si la condition d'exploitation est tellement spécifique qu'aucun attaquant ne la réunit.
A contrario, une XSS (Cross-Site Scripting, injection de code malveillant dans le navigateur d'un autre utilisateur) notée "Low" ou "Medium" peut être présente dans 80 % des apps Symfony et exploitée dès demain matin.
La méthode de scoring EPSS (Exploit Prediction Scoring System) existe précisément pour combler ce manque. Elle tente d'estimer la probabilité qu'une vulnérabilité soit exploitée dans la vraie vie dans les 30 prochains jours, indépendamment de son impact théorique. Malheureusement, les scores EPSS officiels ne sont pas encore disponibles pour ce batch de vulnérabilités.
J'ai donc construit ma propre grille d'exploitabilité, inspirée de cette logique, autour de trois facteurs.
La probabilité que le pattern vulnérable soit déployé : est-ce que la feature concernée est commune ou exotique dans l'écosystème Symfony ?
La probabilité que l'attaquant atteigne la surface d'attaque : faut-il être admin, utilisateur authentifié, ou n'importe qui sur internet ?
La probabilité que l'exploit technique réussisse : est-ce que la condition est réaliste, ou cumule-t-on Y prérequis indépendants qui doivent tous être vrais simultanément ?
Le score final va de 0 à 10. Et bien entendu, ce n'est pas une science exacte. C'est un outil que je vous propose pour forcer la réflexion et vous éviter de mobiliser votre équipe entière pendant trois jours sur une CVE qui ne vous concerne pas.
Voici ce que ça donne sur les 17 CVE Symfony de ce batch.
Les CVE discrètes qui méritent votre attention
Pas de RCE, pas de score CVSS affolant, rien qui justifie un post d'alerte. Et pourtant, ce sont celles que j'aurais vérifiées en premier dans une app Symfony, parce qu'elles touchent des patterns banals, des features qu'on active sans y penser, et des configurations par défaut qu'on ne remet jamais en question.
CVE-2026-46637 : quand le filtre Markdown désactive silencieusement la protection XSS
Score d'exploitabilité : 6/10. La plus haute de tout le batch.
Pour comprendre cette vulnérabilité, il faut d'abord comprendre le mécanisme d'autoescape de Twig. Par défaut, Twig protège automatiquement tout ce qui est affiché dans un template en échappant les caractères HTML dangereux : un <script> dans une variable devient <script> inoffensif dans le navigateur. C'est la protection de base contre les XSS.
Twig offre cependant un mécanisme d'exception : un filtre peut se déclarer is_safe, signalant que sa sortie est déjà sûre et que l'autoescape doit être désactivé pour lui. C'est une fonctionnalité légitime, par exemple pour un filtre qui génère du HTML structuré qu'on ne veut pas voir double-échappé.
Le filtre |markdown_to_html, fourni par le package twig/markdown-extra, s'est déclaré is_safe => ['all'] dans son code interne.
Conséquence : Twig désactive son autoescape sur tout ce que ce filtre produit, quel que soit le contexte, même si le développeur est dans un bloc {% autoescape "html" %}. Le développeur n'a rien écrit de dangereux. Il n'y a rien d'anormal à lire dans ses templates. La protection disparaît silencieusement à cause d'une déclaration dans le code interne du filtre.
Il y a un deuxième dimension à cette CVE. league/commonmark, la librairie Markdown la plus utilisée dans l'écosystème PHP, configure html_input: 'allow' par défaut dans son Environment.php. Ça signifie que le HTML brut dans le contenu Markdown passe intégralement à travers le convertisseur sans être touché. Un utilisateur qui écrit <script>alert(document.cookie)</script> dans un champ Markdown voit son payload survivre à toute la chaîne, Twig ne le protège pas, et le script s'exécute dans le navigateur de la prochaine personne qui lit la page. C'est une XSS stockée.
Ce qui justifie le score de 6/10 : le filtre |markdown_to_html sur du contenu utilisateur est une pratique courante de nos jours (champs de description, commentaires, wikis internes, CMS), n'importe quel utilisateur authentifié peut déclencher l'exploit, et la double absence de protection par défaut, côté twig/markdown-extra et côté league/commonmark, rend l'exploit immédiat sans configuration particulière. C'est la combinaison des trois facteurs au maximum qui pousse le score aussi haut.
CVE-2026-45065: la locale vietnamienne qui génère un redirect vers evil.com
Score d'exploitabilité : 5/10.
Le routing multilingue avec {_locale} dans le path, c'est du Symfony de tous les jours. La documentation officielle montre ce pattern. Et des milliers d'applications utilisent cette fonctionnalité.
Le bug est dans la façon dont Symfony génère la regex de validation pour les requirements d'une route. Pour un requirement comme _locale: 'ar|bg|vi|zh_CN', le Router Symfony génère la regex #^ar|bg|vi|zh_CN$#i. Sans parenthèses autour des alternatives, l'opérateur ^ n'ancre que ar et $ n'ancre que zh_CN. Toutes les alternatives du milieu sont des sous-chaînes non ancrées, validées n'importe où dans la chaîne testée.
Conséquence concrète : la valeur /evil.com passe la validation parce qu'elle contient vi, le code locale du vietnamien. Le générateur d'URL Symfony insère ensuite la valeur brute dans le chemin. /{_locale}/shop devient //evil.com/shop, une URL schéma-relative que le navigateur interprète comme une navigation vers evil.com. C'est ce qu'on appelle un open redirect : l'app légitime redirige l'utilisateur vers un site contrôlé par l'attaquant, en portant l'apparence de confiance du domaine original.
Le mécanisme est automatique du côté du Router. Le développeur ne voit pas qu'il produit un open redirect.
Le score de 5/10 reflète ce paradoxe : le pattern {_locale} dans le path est très répandu et la surface d'attaque est accessible sans authentification, mais l'impact reste limité à un redirect, pas une compromission directe du serveur. C'est une CVE discrète, avec un impact concret en phishing ciblé.
CVE-2026-45071: le parseur XML qui exfiltre vos fichiers locaux
Score d'exploitabilité : 5/10. C'est celle que j'ai trouvée la plus sous-estimée du batch.
Une XXE (XML External Entity) est une attaque qui exploite le mécanisme de résolution d'entités externes du standard XML. Quand un parseur XML est configuré pour résoudre ces entités, un attaquant peut lui faire lire des fichiers locaux du serveur en les référençant comme des entités dans le document soumis.
DomCrawler::addXmlContent() utilise DOMDocument avec validateOnParse = true, ce qui active la résolution des entités externes. Un payload comme celui-la force l'appel à une entité externe :
<?xml version="1.0"?>
<!DOCTYPE r [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<r>&xxe;</r>
Le flag LIBXML_NONET est tout de même présent par défaut, ce qui bloque effectivement les entités importées via le réseau (http, ftp). Mais il ne bloque pas file://. La lecture de fichiers locaux fonctionne malgré ce flag (testée sur PHP 8.4). DOMDocument résout alors les entités file:// sans qu'on le lui demande explicitement.
Ce qui rend cette CVE plus large qu'elle n'y paraît : c'est que Crawler::addContent() bascule automatiquement vers addXmlContent() pour tout contenu commençant par <?xml, ce qui inclut les flux RSS et Atom. Une app qui consomme des feeds externes via le Crawler est vulnérable si un seul fournisseur est compromis ou malveillant, sans que ça passe par un formulaire utilisateur. L'attaquant agit en amont, discrètement. Et les systèmes legacy qui maintiennent des intégrations XML sont précisément ceux où les pratiques de sécurité sont les moins à jour.
L'exfiltration est contrainte, car le flag LIBXML_NONET coupe les requêtes réseau automatiques, et les données restent dans le DOM. Mais si l'app stocke ou affiche ce qu'elle parse, le contenu des fichiers locaux peut ressortir in-band : dans une réponse HTTP, une notification email, un log.
Le score de 5/10 tient à cette double réalité : la surface est plus large que "XML en user-input direct" (tout consommateur de flux RSS/Atom est potentiellement concerné), la technique est triviale quand la surface d'attaque est présente, mais l'exfiltration requiert un canal de lecture en plus de la compromission du flux. Ce double prérequis plafonne le score malgré la technique accessible.
Trois autres CVE de ce batch méritent d'être sur votre radar, avec une exploitabilité moindre mais des patterns suffisamment répandus pour ne pas les ignorer.
CVE-2026-45067: injection de headers email
Score d'exploitabilité : 5/10.
Le composant MIME de Symfony accepte le format "quoted-string RFC 5321" pour les adresses email. Un display name contenant des CRLF bruts les insère tels quels dans les headers du message, permettant d'injecter un Bcc: ou un Content-Type: arbitraire.
La condition : une adresse email soumise par un utilisateur qui atteindrait directement dans un objet de type Address sans aucune validation préalable. Toute app avec un formulaire de contact ou d'invitation est potentiellement concernée.
Ce qui ne fait pas bruler le score au-dessus des 5/10 : des validations comme filter_var($email, FILTER_VALIDATE_EMAIL) sont souvent présente, et rejette les quoted-strings avec CRLF. Idem pour les Assert\Email du composant Symfony Validator. Pour en rajouter une couche, les MTA modernes (Postfix, SendGrid, Exchange) filtrent fréquemment ces caractères avant transmission.
CVE-2026-45066: trois bypasses de la politique allowLinkHosts dans HtmlSanitizer
Le composant HtmlSanitizer de Symfony est conçu pour nettoyer du HTML soumis par un utilisateur : il supprime les balises dangereuses, les attributs non autorisés, et peut restreindre les URLs des liens à une liste de domaines de confiance via la méthode allowLinkHosts(). Concrètement, si vous configurez allowLinkHosts(['monsite.com']), un lien vers evil.com doit être bloqué. Trois possibilités de bypass de cette protection ont été identifiées.
La première exploite le comportement divergent des parseurs d'URL. Un backslash dans l'URL, comme https://monsite.com\@evil.com, est interprété différemment selon le contexte : le parseur RFC le lit comme faisant partie du host légitime et laisse passer la validation, mais le navigateur le normalise en slash et navigue vers evil.com. Le lien passe le filtre mais redirige vers le mauvais domaine.
La seconde concerne la configuration allowRelativeLinks(true). Quand cette option est activée, une URL malformée comme https:/evil.com/, avec un seul slash au lieu de deux, n'est pas bloquée par allowLinkHosts() parce que le parseur ne résout pas de host. Certains navigateurs complètent silencieusement ce format en https://evil.com/ et chargent le domaine interdit.
La troisième est plus directe : la balise <area>, utilisée dans les images cliquables HTML, n'était tout simplement pas soumise à la politique appliquée aux <a>. Un lien vers n'importe quel domaine dans une balise <area> passait sans contrôle.
Pour cette CVE, les conditions d'exploitabilités restent spécifiques : HtmlSanitizer doit être configuré avec une restriction de domaines explicite. Pour autant, le composant est de plus en plus connu avec l'adoption du composant sur les CMS Symfony récents.
CVE-2026-45069: Les contrôles JWT en sueur
Score d'exploitabilité : 4/10.
L'objet AccessToken de Symfony Security permet de valider des tokens JWT via un ClaimCheckerManager, dont le rôle est de vérifier que les claims du JWT (expiration, audience, émetteur) respectent les règles attendues.
Le problème : appelé sans son second paramètre $mandatoryClaims, il ne vérifie un claim que s'il est présent dans le JWT. Un JWT sans exp n'est jamais considéré expiré. Un JWT sans aud passe la vérification d'audience. Un JWT sans iss passe la vérification d'émetteur, ce qui ouvre la porte au rejeu d'un token émis pour un autre service.
C'est un cas classique de faux sentiment de sécurité : le code appelle bien check(), les tests passent, mais des JWT mal formés passent aussi. Le développeur a fait quelque chose de correct sans savoir que c'est insuffisant, et rien dans le code ne le signale.
On parle ici d'un bypass de contrôle d'authentification. Sur le papier, ça devrait scorer haut. Et pourtant le score reste à 4/10, pour deux raisons. L'attaquant doit disposer d'un JWT avec une signature valide, il ne peut pas en forger un de toutes pièces. Ensuite la librairie lexik/jwt-authentication-bundle, qui n'est pas affecté par ce bug, reste dominant dans l'écosystème Symfony pour la gestion des JWT. La surface d'attaque réelle se limite aux apps qui ont migré leur système JWT vers le composant natif de Symfony, une adoption encore minoritaire mais en croissance.
CVE-2026-45074: account takeover sur les apps CAS
Score d'exploitabilité : 4/10.
Le protocole CAS (Central Authentication Service) est un système de SSO (Single Sign-On) très répandu dans les environnements académiques et institutionnels français. Le composant Symfony qui l'implémente, Cas2Handler, utilise le header Host de la requête pour construire le paramètre service= envoyé au serveur CAS lors de la validation d'un ticket, sans vérifier que ce header correspond à un host de confiance.
La chaîne d'attaque se déroule en trois temps. L'attaquant envoie une requête à l'app avec un header Host: evil.com forgé : l'app construit alors un redirect CAS avec service=https://evil.com/callback et un ticket est émis pour ce service par le vrai serveur CAS. La victime est redirigée vers https://evil.com/callback?ticket=ST-xxx, une URL qui semble légitime puisqu'elle provient du serveur CAS institutionnel. L'attaquant capture le ticket, le rejoue vers l'app avec le même Host forgé, la validation CAS est cohérente, et une session est ouverte au nom de la victime. C'est un account takeover complet, sans trace anormale dans les logs de l'app.
Ce qui rend la condition d'exploitation moins restrictive qu'elle n'y paraît : trusted_hosts n'est pas configuré par défaut dans Symfony, car le paramètre kernel.trusted_hosts repose sur une variable d'environnement absente dans un projet standard. Et dans un setup nginx + PHP-FPM classique, fastcgi_param HTTP_HOST $http_host transmet le header Host du client tel quel à PHP, sans filtrage. N'importe quel attaquant peut envoyer curl -H "Host: evil.com" vers l'app et déclencher la construction d'une URL forgée.
Le score reste à 4/10 malgré un impact critique parce que CAS est une niche hors du contexte académique et institutionnel, l'étape de phishing est incontournable (la victime doit cliquer et s'authentifier), et les déploiements derrière un CDN ou un WAF normalisent le header Host et coupent le vecteur. Mais dans le périmètre académique français, l'exposition est réelle.
Les critiques sur le papier
Le reste du batch, c'est l'inverse. Des CVE qui impressionnent à la lecture : une RCE, des bypass de sandbox, une usurpation d'identité mTLS. Le genre de vulnérabilités qui nous font vite peur. Mais quand on applique la grille d'exploitabilité, le tableau change. Impact élevé certes, mais des conditions d'exploitation restrictives, des surfaces d'attaques très étroite. Ce sont des vulnérabilités réelles, qui méritent d'être connues. Mais elles ne méritent probablement pas de sonner le branle-bas de combat.
CVE-2026-46640: La RCE Twig via Cache Poisoning
Score d'exploitabilité : 3/10.
Un RCE (Remote Code Execution) est la classe de vulnérabilité la plus grave qui existe : l'attaquant exécute du code arbitraire sur votre serveur. Accès total, exfiltration de données, ransomware, pivot vers d'autres machines. C'est la case "game over" sur le bingo de la sécurité applicative.
Pour cette vulnérabilité, le mécanisme est élaboré. Twig compile les templates en PHP et les stocke dans un cache sur disque. Lors de cette compilation, les noms de macros Twig sont insérés littéralement dans le PHP généré par le compilateur, sans sanitisation. Si un attaquant contrôle le nom d'une macro, il peut y injecter un payload qui ferme proprement la classe PHP en cours de génération, insère du code arbitraire dans le fichier, puis absorbe le reste dans une classe factice pour satisfaire le compilateur :
x;yield from [];}} public function getTemplateName():string{return "";} ... phpinfo(); class __Dummy__{/*
Quand le fichier de cache est chargé par PHP via include_once, le code injecté s'exécute. C'est du cache poisoning qui aboutit à un RCE garanti.
Second angle particulièrement sévère : ce bypass fonctionne même avec la sandbox Twig activée, parce que l'injection se produit à la compilation, avant toute vérification runtime de la sandbox.
Alors pourquoi 3/10 ?
Parce que la condition bloquante est de contrôler le nom d'une macro, pas son contenu ni ses arguments. Les éditeurs de templates permettent généralement d'éditer le corps d'un template, rarement de nommer librement ses macros. Les CMS avec templating utilisateur n'exposent quasiment jamais cette surface d'attaque.
On peut néanmoins imaginer un cas réaliste, si le nom de macro vient d'une entrée base de données dans un constructeur de formulaires dynamique ou un système de reporting.
Dans tout les cas, c'est un pattern d'attaque suffisamment spécifique pour ne pas justifier une mobilisation d'urgence dans la majorité des apps.
Impact catastrophique si la condition est réunie. Mais le chemin jusqu'à la condition est exotique.
Sandbox Twig : 5 CVE à traiter comme une seule question
CVE-2026-46634, CVE-2026-46635, CVE-2026-46638, CVE-2026-46640, et CVE-2026-47732 forment un bloc cohérent. Elles scorent entre 2 et 4/10, pour une raison commune : elles nécessitent toutes que l'app déploie la sandbox Twig pour du templating utilisateur. CVE-2026-46640, détaillée ci-dessus comme le RCE du batch, en fait également partie : l'injection dans les noms de macros contourne précisément la sandbox parce qu'elle opère à la compilation, avant toute vérification runtime.
La sandbox Twig est un mécanisme de restriction qui permet de laisser des utilisateurs non-privilégiés écrire leurs propres templates, en limitant les objets, méthodes et filtres accessibles. Elle n'est pas activée par défaut. Elle sert à certains CMS, des outils de reporting, des constructeurs de formulaires avancés.
C'est un pattern niche. Mais voilà l'observation transversale qui change tout : si votre app est dans ce périmètre, ces cinq CVE deviennent critiques simultanément et se combinent entre elles. Ce ne sont plus cinq bugs isolés.
CVE-2026-47732 expose le contenu d'objets sensibles via l'opérateur matches, qui déclenche __toString() sans vérification sandbox.
CVE-2026-46635 bypasse la whitelist de propriétés via le filtre |column, qui passe directement par array_column() en PHP natif sans jamais appeler les vérifications Twig.
CVE-2026-46634 permet de sortir de la sandbox entièrement via template_from_string, dont le nom synthétique ne correspond à aucune règle de la security policy.
La bonne question à poser n'est pas "est-ce que chacune de ces CVE me concerne ?" C'est : "est-ce que je fais du templating utilisateur Twig ?" Si oui, c'est un sujet à adresser en bloc. Si non, vous pouvez passer à la suite.
Le cluster sandbox illustre des CVE niche parce que le pattern est peu répandu. La CVE suivante est niche pour une raison différente : le pattern existe, mais la condition d'exploitation est verrouillée par la configuration serveur en amont.
CVE-2026-45063: usurpation d'identité mTLS
Score d'exploitabilité : 1/10. Celle qui illustre le mieux l'écart entre impact théorique et probabilité réelle.
Le mTLS (mutual TLS) est un mécanisme d'authentification où le client s'identifie au serveur via un certificat X.509, en plus du certificat serveur habituel. C'est utilisé notamment dans les portails gouvernementaux, les intranets académiques, les API B2B.
Le mécanisme de la vulnérabilité est assez simple à comprendre. La regex qui extrait l'email d'un "Distinguished Name" du certificat est non-ancrée : #emailAddress=([^,/]++)#. Elle peut donc matcher la sous-chaîne emailAddress= n'importe où dans le DN. Un certificat forgé portant CN=emailAddress=admin@corp.com,O=EvilCorp fait croire au composant Security de Symfony que l'identité est admin@corp.com. C'est une usurpation d'identité complète sur une app avec authentification par certificat client.
Mais creusons la condition.
Symfony ne lit jamais le certificat, ni le valide directement. Il fait confiance à ce que le serveur web lui transmet dans $_SERVER, sans vérification. Ce qui signifie que la configuration Apache ou nginx en amont est déterminante.
Avec SSLVerifyClient require, la configuration recommandée pour du mTLS strict, un certificat auto-signé est rejeté au handshake TLS. La variable SSL_CLIENT_S_DN n'est jamais transmise à PHP, et le bypass est impossible avant même que Symfony entre en jeu.
Le vecteur n'existe que dans les configurations SSLVerifyClient optional ou optional_no_ca, où Apache transmet le DN même quand la vérification échoue. C'est un mode qui a des cas d'usage légitimes, mais qui représente une fraction minuscule des déploiements mTLS. Les déploiements gouvernementaux et académiques, le périmètre naturel du mTLS Symfony, utilisent quasi-systématiquement require.
Ainsi, il faudrait qu'un attaquant forge un certificat valide avec le payload à l'interieur. Ce qui est peu probable. C'est exactement ça, l'écart entre sévérité et exploitabilité réelle.
Les CVE à vérifier sans mobilisation prioritaire
Quatre CVE complètent le tableau des scores bas. Elles sont réelles, patchées par Symfony, mais ne justifient pas une haute priorisation dans la grande majorité des contextes.
CVE-2026-45075: Bypass méthode HTTP (3/10). Le router Symfony normalise HEAD en GET pour le dispatch (HEAD et GET sont équivalents selon la RFC), mais les attributs #[IsGranted], #[IsCsrfTokenValid] et #[IsSignatureValid] configurés avec methods: ['GET'] ne font pas cette normalisation. Une requête HEAD bypasse le contrôle parce que HEAD n'est pas dans ['GET']. Le score est bas parce que le paramètre methods sur ces attributs est peu utilisé (la valeur par défaut [] est sûre), et parce que HEAD ne retourne pas de body, ce qui limite l'impact des données exposées.
CVE-2026-46629: DoS mémoire via twig/intl-extra (3/10). Chaque appel aux filtres |format_datetime, |format_date ou |format_time avec un pattern ou une locale distinct crée un objet IntlDateFormatter ICU stocké dans un cache d'instance qui ne se vide jamais. C'est un vecteur de déni de service par épuisement mémoire, pas de compromission. L'effet est borné par requête en PHP-FPM classique, mais devient un DoS progressif concret sur les runtimes long-lived (FrankenPHP, Swoole, RoadRunner).
La condition d'exploitabilité : que l'argument pattern ou locale de ces filtres soit contrôlé par l'utilisateur.
CVE-2026-45068: Arg injection sendmail (2/10). Quand le transport Mailer est configuré sur sendmail, une adresse destinataire comme -X/var/www/html/shell.php@example.com est passée telle quelle au binaire via escapeshellarg, qui empêche l'injection shell mais pas l'injection d'argument. Sendmail interprète le -X comme un flag et écrit un fichier de log au chemin indiqué. La surface d'attaque est quasi-inexistante en production moderne où SMTP ou une API d'envoi est utilisée, mais les apps legacy avec transport sendmail sont concernées.
CVE-2026-45072: XSS WebProfilerBundle (1/10). Une XSS dans l'interface de debug du Profiler Symfony. Inoffensive en production où APP_DEBUG=false désactive le Profiler. C'est le score le plus bas du batch, et la CVE se résout mécaniquement en ayant une configuration de production correcte.
Ce que le ZIP ne contient pas
Reste une question de perspective. Symfony 8.0, c'est plus de 10 000 fichiers PHP et des centaines de milliers de lignes de code, uniquement sur le composant principal.
Alors 19 vulnérabilités sur ce volume de code, c'est peut-être excellent. C'est peut-être aussi le résultat d'une sélection agressive en amont dont on ne connaît pas les critères. Surtout que nous avons vu, que dans ces 19 vulnérabilités, certaines ciblées d'autres composants que le core de symfony.
On ne sait pas combien de findings bruts Mythos a produit au total, ni ce qui a été écarté. Et ça change la façon dont on lit ce chiffre.
Ce que Mythos ne fait pas non plus, c'est trier pour votre contexte. Détecter une vulnérabilité dans l'absolu et évaluer si elle vous concerne, vous, dans votre app, avec votre configuration, ce sont deux choses différentes. Ce travail reste humain, et il reste entièrement à faire. C'est ce que j'ai essayé de faire dans cet article pour vous.
Et c'est là que les chiffres globaux de Glasswing deviennent éloquents. Sur l'ensemble du projet, Anthropic annonce 1 094 vulnérabilités confirmées High ou Critical. 75 patchées à ce jour, sur 530 divulguées. [source]
Anthropic l'admet eux-mêmes : le goulot d'étranglement, c'est la capacité humaine à trier, comprendre, concevoir et déployer des correctifs. Des mainteneurs open source ont demandé à Anthropic de ralentir le rythme des divulgations tant le volume est difficile à absorber. Mythos ne résout pas ce problème. Il l'amplifie.
Conclusion
Alors, est-ce que Mythos trouve des choses qui comptent vraiment ?
La réponse honnête, c'est : oui et non. Certaines CVE de ce batch sont précises, subtiles, non triviales à identifier manuellement. Mais la vulnérabilité la plus dangereuse en pratique, CVE-2026-46637, est avant tout un problème de conception. Le filtre |markdown_to_html porte dans son nom même l'intention de produire du HTML, et la déclaration is_safe => ['all'] en découle logiquement. Sauf qu'elle est trop permissive, et ça aurait mérité d'être davantage travaillé en amont, ou au minimum flagué dans la documentation.
Et dans le même temps, on a vu certaines CVE qui sont franchement tiré par les cheveux comme la CVE-2026-45075 (Bypass des méthodes HTTP sur les contrôles d'authentification).
Ce que ça dit sur Mythos globalement, je reste mitigé. L'outil voit des choses intéressantes. Mais est-ce une révolution ? La vraie question n'est pas la performance du modèle, c'est la capacité humaine à absorber ce qu'il produit. Et sans les chiffres des findings bruts, on ne peut pas calibrer ce que "performant" veut vraiment dire.
Ce qui est certain, c'est que la détection n'est que la première étape. J'ai publié un repo GitHub avec l'analyse technique détaillée des 17 CVE, payload d'exploitation inclus pour chacune, pour que vous puissiez évaluer vous-même si votre configuration est concernée.
Parce que c'est ça, le vrai travail : pas lire un communiqué, mais ouvrir votre code et vérifier.
Le repo GitHub est disponible ici. Les CVE analysées concernent la branche Symfony 8.0.x. Les fixes sont disponibles dans les releases de sécurité Symfony correspondantes.