SnakeYaml 2.0 : résoudre la vulnérabilité de désérialisation non sécurisée
21 juin 2023
0 minutes de lectureEn décembre dernier, nous vous avons signalé CVE-2022-1471. Dans certaines circonstances, ce problème de désérialisation non sécurisée pouvait facilement entraîner l’exécution de code arbitraire.
Dans l’article détaillé « Vulnérabilité de désérialisation non sécurisée dans SnakeYaml (CVE-2022-1471) », j’ai expliqué les problèmes de cette bibliothèque et comment cette vulnérabilité pouvait être exploitée. En résumé, par défaut, SnakeYaml analysait le YAML entrant en le convertissant en type d’objet générique. Cela permettait de désérialiser d’autres classes disponibles dans le classpath. Même si une ClassCastException est déclenchée, si l’objet a déjà été chargé, le mal est fait.
L’impact dépend fortement de la façon dont vous utilisez la bibliothèque. Par exemple, de nombreux développeurs utilisent uniquement le YAML pour fournir des fichiers de configuration à leurs applications. Cette vulnérabilité n’est exploitable que si vous acceptez des fichiers YAML provenant de sources inconnues, comme les utilisateurs finaux. Néanmoins, nous ne pouvons tout simplement pas prévoir comment les utilisateurs exploiteront une bibliothèque de ce type, et les paramètres par défaut doivent être sécurisés.
Mettre à niveau SnakeYaml avec Snyk Open Source
Utilisons Snyk Open Source pour trouver une solution de remplacement à l’ancienne bibliothèque SnakeYaml. Lorsque j’exécute localement snyk test avec la CLI Snyk, je vois qu’une solution de remplacement est disponible.

L’interface Web m’indique également qu’une version 2.0 de SnakeYaml est disponible pour résoudre le problème. Le seul souci, c’est que Spring Boot 3 intègre toujours la version 1.x. Je dois donc remplacer manuellement la version dans mon fichier manifeste Maven ou Gradle.

Attention : remplacer manuellement la bibliothèque par une nouvelle version majeure peut entraîner des problèmes. Ne faites pas ces modifications sans réfléchir, et tenez compte de leur impact potentiel sur le fonctionnement interne de votre application.
Atténuer les risques liés à la désérialisation avec SnakeYaml 2.0
SnakeYaml 2.0 est sorti début 2023 afin d’atténuer le comportement par défaut susceptible d’entraîner l’exécution de code arbitraire. Dans cette version, le constructeur utilisé par chaque nouvel objet yaml() étend désormais SafeConstructor. Par conséquent, nous ne pouvons analyser qu’un ensemble limité de types. SafeConstructor de SnakeYaml peut construire des classes Java standard, comme les types primitifs et des classes de base telles que String et Map.
Par défaut, il n’est désormais plus possible d’analyser des types spécifiques. Le fichier YAML ci-dessous déclenchera donc une exception :
L’implémentation par défaut n’est donc plus vulnérable. Cependant, il s’agit d’une modification incompatible : votre code initial ne fonctionnera probablement plus.
Comment corriger ma logique d’analyse YAML avec SnakeYaml 2.x
Avant tout, nous devons nous assurer de ne plus utiliser SnakeYaml 1.x. Même la dernière version de Spring Boot 3.1 n’intègre actuellement pas SnakeYaml 2.x. Nous devons donc effectuer la mise à niveau nous-mêmes dans notre fichier manifeste. Pour les projets Maven, nous pouvons utiliser la section <dependencyManagement> du fichier pom, entre autres. Avec Gradle, il est également possible de mettre à jour les dépendances transitives à l’aide des contraintes de dépendance.
Notez que SnakeYaml 2.x introduit des modifications incompatibles dans l’API par rapport aux versions précédentes. Nous devons donc réécrire notre implémentation d’analyse YAML pour qu’elle utilise les nouveaux paramètres sécurisés par défaut et fonctionne à nouveau.
Prenons un domaine très simple qui comporte deux classes :
Personne
Commentaire
Person.java :
Comment.java :
Si vous souhaitez créer un fichier YAML à partir d’une entité comme celle ci-dessus, vous avez probablement écrit quelque chose de similaire avec SnakeYaml 1.x :
Cela produit le fichier YAML suivant :
Avec SnakeYaml 2.x, !!mypackage.Person n’est plus accepté. Nous pouvons désormais supprimer la référence à l’objet lors de l’analyse de l’objet dans un fichier YAML. Cependant, les fichiers YAML exportés avant cette migration posent toujours problème.
Heureusement, il existe toujours une solution ! Lors de l’analyse d’un objet spécifique, vous pouvez définir le constructeur que l’analyseur doit utiliser. Vous pouvez également ajouter un TagInspector spécifique aux LoaderOptions pour autoriser le tag de notre package. Vous pouvez ainsi n’autoriser que les fichiers YAML correspondant à votre objet, tout en restant compatible avec les fichiers YAML créés précédemment avec les versions 1.x.
Il serait également préférable de supprimer entièrement de votre fichier YAML la référence ou le tag correspondant à l’objet lui-même. C’était déjà possible dans les versions précédentes de SnakeYaml : il suffisait d’ajouter un representer à votre objet YAML pour convertir le tag de l’objet de premier niveau en map. Voici un exemple compatible avec SnakeYaml 2.x :
Le fichier YAML ne commencera plus par !!mypackage.Person (ou une valeur similaire). Si tous vos fichiers YAML sont propres, vous pouvez supprimer TagInspector de votre analyseur.
Restez à jour avec Snyk
Il est essentiel pour la sécurité des logiciels open source de maintenir toutes les versions de vos bibliothèques à jour. Utiliser SnakeYaml 1.x peut entraîner des problèmes de sécurité évitables si vous acceptez directement ou indirectement des fichiers YAML provenant de sources externes.
Snyk Open Source vous aide à détecter et à corriger ces problèmes, ou vous indique une autre version si nécessaire. L’exemple ci-dessous montre que la mise à niveau vers SnakeYaml 2.0 ou une version ultérieure élimine la vulnérabilité d’exécution de code arbitraire.

De plus, si vous connectez votre dépôt Git à Snyk, nous pouvons vous proposer des demandes de tirage pour maintenir vos dépendances à jour, même en l’absence de problème de sécurité critique. Mieux vaut prévenir que guérir : maintenir vos bibliothèques à jour vous aide à réduire le risque de vulnérabilités et à éviter le travail supplémentaire qu’entraîne une mise à jour effectuée à la suite d’un problème de sécurité.

Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis de capture du drapeau en regardant à la demande notre atelier virtuel d’initiation.


