veilletech.fr
5 nov. Feed du jour
#03 SYMFONY Article

Symfony : huit avis, correctifs en 7.4.23 et 8.1.11

Vos règles d'accès nginx doivent survivre à /index.phpadmin.

Symfony publie huit avis de sécurité corrigés dans 5.4.56, 6.4.50, 7.4.23 et 8.1.11. Les plus lourds : un champ UploadedFile désérialisé depuis la requête peut désigner n'importe quel fichier du serveur (CVE-2026-118515), HttpFoundation peut générer des URL vers un hôte choisi par le client, et une règle nginx, Apache ou CDN sur /admin se contourne avec /index.phpadmin.

4 min de lectureintermédiairevidéo 1:25
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. À lire en premier : cinq avis, trois sujets
  3. Les trois autres, en bref
  4. Comment s'y prendre
  5. À retenir

Ce qui se passe

Le 4 novembre 2026, l'équipe Symfony a publié huit avis de sécurité en même temps. Ils sont tous corrigés par les mêmes versions : 5.4.56, 6.4.50, 7.4.23 et 8.1.11 (HtmlSanitizer, apparu en 6.1, n'a pas de 5.4). Les patchs sont aussi reportés sur la 8.2. Aucun des huit avis ne signale d'attaque en cours, et plusieurs ne valent que pour une configuration précise.

Avis Composant Effet
CVE-2026-118515 Serializer UploadedFile construit depuis les données de la requête : n'importe quel fichier du serveur passe pour un envoi
GHSA-pxj9-jh84-vhm5 Serializer DATA: en majuscules ouvert comme chemin local
GHSA-5mx8-mwrp-5693 HttpFoundation URL générées vers un hôte choisi par le client
GHSA-3h27-hjv7-fqjx HttpFoundation Règles placées devant PHP contournées par /index.phpadmin
CVE-2026-118513 Security HTTP Authentificateur X509 : l'identifiant se lit dans une virgule échappée du CN
CVE-2026-118517 HtmlSanitizer Liste d'hôtes autorisés contournée par http:evil.example (gravité faible)
GHSA-6prc-h956-hxjq Filesystem Path prend tout préfixe avant :// pour une racine
GHSA-8f57-m8wj-x65w Security HTTP Les connexions programmatiques sautent checkPostAuth()

À lire en premier : cinq avis, trois sujets

1. Un champ UploadedFile désigne un fichier du serveur

DataUriNormalizer ne construit que SplFileInfo, SplFileObject et File. Une propriété typée UploadedFile était laissée à ObjectNormalizer, qui l'instanciait par son constructeur à partir des données reçues, y compris le chemin et le drapeau test. Avec #[MapRequestPayload] et un DTO portant une propriété UploadedFile, la requête n'a pas besoin d'envoyer le moindre fichier : elle nomme un fichier du serveur, et l'application le traite comme un envoi. Selon l'usage, cela expose tout fichier lisible par PHP, ou le déplace quand move() est appelé comme dans la documentation. Assert\File n'y change rien, puisqu'il valide le vrai fichier du serveur.

Le cas voisin, GHSA-pxj9-jh84-vhm5, joue sur la casse : l'expression de DataUriNormalizer accepte DATA: ou Data:, mais PHP n'active son flux data: que pour la forme minuscule. Autrement, il ouvre la chaîne comme un chemin local et résout les .. : DATA:,/../../../../../../etc/hostname livre le contenu de /etc/hostname. FrameworkBundle enregistre ce normaliseur par défaut.

2. Des URL générées vers l'hôte de l'attaquant

Quand Request::getBaseUrl() ne trouve pas le nom du script au début de l'URI, il le cherche plus loin et garde tout ce qui précède, partie que le client choisit. Une URI commençant par // ou /\ donne alors une base qui débute par un hôte. Sont touchées les applications dont le point d'entrée est dans un sous-dossier, par exemple avec un .htaccess qui réécrit tout vers public/, ainsi que certaines configurations nginx sans fastcgi_split_path_info et php -S avec un routeur hors de la racine. Les configurations recommandées par la documentation ne sont pas touchées. framework.trusted_hosts n'aide pas, l'hôte de la requête étant le vrai.

evil.exampleApplicationUtilisateurAttaquantevil.exampleApplicationUtilisateurAttaquantLien avec // dans le chemin1Ouvre la page de connexion2Formulaire dont l'action viseevil.example3Envoie identifiant et mot de passe4
Le lien piégé fait générer à Symfony un formulaire qui pointe ailleurs

Même famille, GHSA-3h27-hjv7-fqjx : depuis le correctif de CVE-2025-64500, getPathInfo() retire le nom du script du début de l'URL même quand il n'est que le début d'un segment plus long. Avec SCRIPT_NAME=/index.php, /index.phpadmin est routé comme /admin. Les règles de Symfony (access_control, pare-feux) lisent le même chemin et restent cohérentes ; celles placées devant PHP ne le sont pas : un location /admin nginx, un <Location /admin> Apache ou une règle de CDN ou de WAF. La configuration nginx de la documentation et le .htaccess de symfony/apache-pack rendent /index.php/admin inaccessible mais laissent passer /index.phpadmin.

3. Une virgule échappée dans un certificat

CVE-2026-118513, correctif incomplet de CVE-2026-45063 : X509Authenticator cherche emailAddress= dans le DN déjà sérialisé, sans distinguer une virgule qui sépare deux attributs d'une virgule échappée dans une valeur. Un certificat dont le CN vaut jdoe,emailAddress=admin@example.com authentifie alors comme admin@example.com. Il faut détenir un certificat de l'autorité de confiance de l'application et pouvoir influencer le CN. Les applications qui passent un userKey par attribut, comme SSL_CLIENT_S_DN_Email, ne sont pas touchées.

Les trois autres, en bref

Comment s'y prendre

Terminal
composer show 'symfony/*' | grep -E 'http-foundation|serializer|security-http|filesystem|html-sanitizer'
composer update 'symfony/*'

Puis relire les DTO qui portent un UploadedFile sous #[MapRequestPayload], et tester /index.phpadmin contre vos règles d'accès nginx, Apache ou CDN.

Source : le blog Symfony et ses sept autres avis du 4 novembre (GHSA-pxj9, GHSA-5mx8, GHSA-3h27, CVE-2026-118513, CVE-2026-118517, GHSA-6prc, GHSA-8f57). Source en anglais.