Labo de recherche et de reproduction contrôlées de vulnérabilités pour CVE-2020-14343 dans PyYAML
Ce projet illustre la CVE-2020-14343 dans un environnement Docker contrôlé et isolé.
Le laboratoire contient deux environnements :
yaml.safe_load()Le laboratoire illustre le cycle de vie complet de la vulnérabilité :
La charge utile de reproduction utilisée dans ce laboratoire est volontairement inoffensive et se contente d'afficher un marqueur de test.
| Propriété | Détails |
|---|---|
| CVE | CVE-2020-14343 |
| Produit | PyYAML |
| Versions affectées | Versions antérieures à 5.4 |
| Version corrigée | 5.4 |
| Type de vulnérabilité | Validation d'entrée incorrecte (CWE-20) |
| Gravité | Critique |
| Surface d'attaque | Entrée YAML traitée à l'aide d'une fonctionnalité de chargement vulnérable |
| CVSS | 9.3 (CVSS v4, GitHub Advisory) |
La vulnérabilité se produit lorsqu'une entrée YAML non fiable est traitée à l'aide d'une fonctionnalité de chargement vulnérable de PyYAML.
Les versions de PyYAML antérieures à 5.4 autorisaient des balises YAML spécialement conçues, notamment des balises spécifiques à Python telles que :
!!python/object/new
pour atteindre les fonctionnalités de construction d'objets lorsque FullLoader était utilisé.
Un document YAML malveillant peut donc provoquer une exécution involontaire de code Python.
Le problème était lié à un correctif incomplet pour une vulnérabilité PyYAML antérieure.
PyYAML 5.4 a corrigé CVE-2020-14343 en déplaçant les balises Python arbitraires vers UnsafeLoader.
Pour les applications traitant du YAML non fiable, ce lab utilise également yaml.safe_load() comme approche de chargement sécurisée.
Le lab contient deux services Docker isolés :
Host Machine
|
+------------+------------+
| |
v v
Vulnerable App Patched App
localhost:5000 localhost:5001
| |
PyYAML 5.3.1 PyYAML 5.4
FullLoader SafeLoader
| |
v v
Payload executes Payload rejected
| Service | Port hôte | Port conteneur | PyYAML | Objectif |
|---|---|---|---|---|
| vulnerable | 5000 | 5000 | 5.3.1 | Environnement vulnérable |
| patched | 5001 | 5000 | 5.4 | Environnement corrigé |
cve-2020-14343-lab/
├── vulnerable/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── patched/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── exploit/
│ └── reproduce.py
├── detection/
│ └── detect.py
├── screenshots/
│ ├── 01-docker-compose-running.png
│ ├── 02-vulnerable-detection.png
│ ├── 03-patched-detection.png
│ ├── 04a-vulnerable-request.png
│ ├── 04b-vulnerable-execution-log.png
│ └── 05-patched-exploit-blocked.png
├── blog/
│ └── CVE-2020-14343-Technical-Blog.pdf
├── docker-compose.yml
├── README.md
└── .gitignore
| Fichier/Répertoire | Objectif |
|---|---|
vulnerable/app.py | Application Flask utilisant un chargement YAML vulnérable |
vulnerable/Dockerfile | Construit l'image Docker vulnérable |
vulnerable/requirements.txt | Fixe PyYAML à la version 5.3.1 |
patched/app.py | Application Flask utilisant un chargement YAML sécurisé |
patched/Dockerfile | Construit l'image Docker corrigée |
patched/requirements.txt | Fixe PyYAML à la version 5.4 |
exploit/reproduce.py | Reproduit la vulnérabilité à l'aide d'une charge utile contrôlée |
detection/detect.py | Vérifie la version de PyYAML à l'intérieur d'un conteneur Docker |
docker-compose.yml | Construit et exécute les deux environnements |
screenshots/ | Contient les preuves capturées pendant le lab |
blog/ | Contient le PDF du blog technique de 800 à 1200 mots |
Les logiciels suivants sont requis :
Docker Desktop doit être en cours d'exécution avant de démarrer le lab.
L'application vulnérable est intentionnellement exposée uniquement sur la machine locale via les mappages de ports Docker.
Depuis le répertoire racine du projet, exécutez :
docker compose up --build -d
Exécutez :
docker compose ps
Les deux services doivent afficher Up.
Ouvrez :
http://127.0.0.1:5000
I'm ready to translate chunk 13, but the INPUT section appears to be empty — no source text was included after "INPUT:".
Please provide the Markdown content for chunk 13, and I'll return the French translation following all the rules you specified.
{
"message": "CVE-2020-14343 vulnerable YAML parser"
}
Ouvrir :
http://127.0.0.1:5001
I'm ready to translate chunk 13, but the INPUT section appears to be empty — no source text was included after "INPUT:".
Please provide the Markdown content for chunk 13, and I'll return the French translation following all the rules you specified.
{
"message": "CVE-2020-14343 patched YAML parser"
}
docker compose up -d
docker compose down
docker compose up --build -d
docker compose ps
docker logs cve-vulnerable
docker logs cve-patched
L'application vulnérable expose un point de terminaison /parse qui accepte une entrée YAML.
L'environnement vulnérable utilise :
yaml.FullLoaderLe script de reproduction se trouve à l'emplacement suivant :
exploit/reproduce.py
L'application vulnérable est disponible à l'adresse :
http://127.0.0.1:5000/parse
Exécuter :
python exploit/reproduce.py
Le script envoie une charge utile YAML contrôlée contenant une balise YAML spécifique à Python.
Dans l'environnement vulnérable, la charge utile est acceptée et l'application renvoie une réponse HTTP 200.
Le marqueur de test contrôlé :
CVE-2020-14343-TEST
est exécuté à l'intérieur du conteneur de l'application vulnérable.
L'exécution peut être vérifiée à l'aide de :
docker logs cve-vulnerable
La sortie de journal attendue comprend :
CVE-2020-14343-TEST
Cela démontre l'exécution de code via le comportement de chargement YAML vulnérable.
La charge utile de reproduction est intentionnellement inoffensive. Elle se contente d'afficher un marqueur de test et ne modifie pas le système hôte, n'accède pas aux identifiants, n'accède pas aux données sensibles, n'interagit pas avec des systèmes externes et n'effectue aucune action destructive.