Les bibliothèques python Yaml sont également capables de sérialiser des objets python et non seulement des données brutes:
print(yaml.dump(str("lol")))
lol
...
print(yaml.dump(tuple("lol")))
!!python/tuple
- l
- o
- l
print(yaml.dump(range(1,10)))
!!python/object/apply:builtins.range
- 1
- 10
- 1
Vérifiez comment le tuple n'est pas un type de données brut et donc il a été sérialisé. Et la même chose s'est produite avec le range (pris dans les fonctions intégrées).
safe_load() ou safe_load_all() utilise SafeLoader et ne prend pas en charge la désérialisation des objets de classe. Exemple de désérialisation d'objet de classe:
import yamlfrom yaml import UnsafeLoader, FullLoader, Loaderdata =b'!!python/object/apply:builtins.range [1, 10, 1]'print(yaml.load(data, Loader=UnsafeLoader))#range(1, 10)print(yaml.load(data, Loader=Loader))#range(1, 10)print(yaml.load_all(data))#<generator object load_all at 0x7fc4c6d8f040>print(yaml.load_all(data, Loader=Loader))#<generator object load_all at 0x7fc4c6d8f040>print(yaml.load_all(data, Loader=UnsafeLoader))#<generator object load_all at 0x7fc4c6d8f040>print(yaml.load_all(data, Loader=FullLoader))#<generator object load_all at 0x7fc4c6d8f040>print(yaml.unsafe_load(data))#range(1, 10)print(yaml.full_load_all(data))#<generator object load_all at 0x7fc4c6d8f040>print(yaml.unsafe_load_all(data))#<generator object load_all at 0x7fc4c6d8f040>#The other ways to load data will through an error as they won't even attempt to#deserialize the python object
Le code précédent utilisait unsafe_load pour charger la classe Python sérialisée. Cela est dû au fait que dans la version >= 5.1, il n'autorise pas de désérialiser une classe Python sérialisée ou un attribut de classe, avec Loader non spécifié dans load() ou Loader=SafeLoader.
Les anciennes versions de pyyaml étaient vulnérables aux attaques de désérialisation si vous n'avez pas spécifié le Loader lors du chargement de quelque chose : yaml.load(data)
Notez que dans les versions récentes, vous ne pouvez plus appeler .load()sans un Loader et le FullLoader n'est plus vulnérable à cette attaque.
RCE
Des charges utiles personnalisées peuvent être créées en utilisant des modules YAML Python tels que PyYAML ou ruamel.yaml. Ces charges utiles peuvent exploiter des vulnérabilités dans les systèmes qui désérialisent des entrées non fiables sans une désinfection appropriée.