
Preuve de concept reproduisant CVE-2026-8932, une faille de correspondance de configuration mTLS incomplète dans la réutilisation de connexion de libcurl, avec un serveur de laboratoire local et un PoC en C.
Reproduction de preuve de concept de CVE-2026-8932, un problème de correspondance de configuration mTLS incomplète dans la réutilisation de connexion de libcurl.
CVE-2026-8932 affecte la logique de réutilisation de connexion de libcurl lorsque la configuration de TLS mutuel (mTLS) change entre les requêtes.
Dans des conditions vulnérables, libcurl peut réutiliser une connexion TLS existante alors même qu'une option de configuration liée à mTLS a changé et aurait dû empêcher la réutilisation de cette connexion.
Cette PoC démontre le problème en changeant le mot de passe de la clé privée entre deux requêtes tout en utilisant le même certificat client et la même clé privée.
La première requête utilise le mot de passe correct :
correct-password
La seconde requête utilise intentionnellement un mot de passe invalide :
WRONG-PASSWORD
Si libcurl réutilise incorrectement la connexion TLS existante, la seconde requête ne nécessite pas un autre handshake TLS. Par conséquent, le mot de passe de clé privée invalide n'est jamais nécessaire pour établir une nouvelle connexion TLS et la requête réussit.
Le PoC démontre donc la condition de réutilisation de connexion associée à CVE-2026-8932.
| Propriété | Valeur |
|---|---|
| CVE | CVE-2026-8932 |
| Composant | libcurl |
| Type de vulnérabilité | Correspondance incomplète de configuration mTLS |
| CWE | CWE-305 — Contournement d'authentification par faiblesse primaire |
| Zone affectée | Réutilisation de connexion TLS |
| Protocole | HTTPS / mTLS |
| Client | API libcurl |
| CLI curl | Non affecté |
| Périmètre du PoC | Environnement de laboratoire local |
La vulnérabilité est un problème de correspondance logique/configuration, plutôt qu'une vulnérabilité classique de sécurité mémoire telle qu'un débordement de tampon ou un use-after-free.
libcurl conserve les informations de connexion et peut réutiliser une connexion existante lorsqu'une requête ultérieure est considérée comme compatible avec la configuration de la connexion.
Pour les connexions TLS, la configuration de la connexion doit donc être comparée avec soin avant réutilisation.
L'implémentation vulnérable n'incluait pas tous les champs de configuration mTLS pertinents dans la logique de correspondance des connexions.
Parmi les paramètres affectés figurent :
cert_type
key
key_type
key_passwd
key_blob
Le paramètre important utilisé par ce PoC est :
key_passwd
Le PoC établit une connexion TLS en utilisant une clé privée client chiffrée et le mot de passe correct :
correct-password
Il effectue ensuite une autre requête en utilisant le même certificat et la même clé, mais change le mot de passe en :
WRONG-PASSWORD
Une implémentation vulnérable de la mise en correspondance des connexions peut encore considérer la connexion existante comme réutilisable.
Le test consiste en deux requêtes HTTP.
La première requête établit la connexion TLS :
URL:
https://server.test:8443/A
Client certificate:
client.crt
Private key:
client.key
Key password:
correct-password
La connexion TLS reste persistante car le serveur prend en charge le keep-alive HTTP.
La deuxième requête utilise le même certificat et la même clé privée, mais modifie le mot de passe de la clé :
URL:
https://server.test:8443/B
Client certificate:
client.crt
Private key:
client.key
Key password:
WRONG-PASSWORD
Si libcurl crée une nouvelle connexion TLS, le chargement de la clé privée chiffrée avec un mot de passe erroné devrait échouer.
Cependant, si libcurl réutilise incorrectement la connexion existante, aucune nouvelle poignée de main TLS n'est requise.
Le mot de passe invalide n'empêche donc pas la requête HTTP de réussir.
La configuration du laboratoire se compose de :
localhost
|
v
+---------------------+
| Python mTLS Server |
| 127.0.0.1:8443 |
+----------+----------+
|
| HTTPS / TLS 1.3
|
+--------+--------+
| |
/A /B
\ /
\ /
v v
Same TLS Connection
|
v
libcurl
PoC (C)
L'observation importante est que /A et /B doivent arriver sur la même connexion TLS.
CVE-2026-8932-PoC/
├── README.md
├── LICENSE
├── .gitignore
│
├── certs/
│ └── .gitkeep
│
├── poc/
│ └── poc.c
│
├── server/
│ └── server.py
│
└── docs/
├── CVE-2026-8932-POC.jpg
├── CVE-2026-8932-server-POC.jpg
├── poc-output.txt
└── server-output.txt
Le répertoire certs/ est volontairement laissé vide dans le dépôt. Les certificats et les clés privées doivent être générés localement.
Le PoC a été testé dans l'environnement suivant :
OS:
Debian GNU/Linux 13 (trixie)
Architecture:
x86_64
libcurl:
8.14.1
OpenSSL:
3.5.7
GCC:
14.2.0
L'installation vulnérable de libcurl utilisée pour la reproduction était :
libcurl/8.14.1
Vérifiez la version installée :
curl --version
et :
pkg-config --modversion libcurl
mkdir -p ~/cve-2026-8932-lab/{certs,poc,server,docs}
cd ~/cve-2026-8932-lab
cd ~/cve-2026-8932-lab/certs
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes \
-key ca.key \
-sha256 \
-days 3650 \
-subj "/CN=CVE-2026-8932-CA" \
-out ca.crt
Générez la clé privée du serveur :
openssl genrsa -out server.key 2048
Générez la CSR :
openssl req -new \
-key server.key \
-subj "/CN=server.test" \
-out server.csr
Créez les extensions de certificat :
printf "subjectAltName=DNS:server.test\nextendedKeyUsage=serverAuth\n" \
> server.ext
Signez le certificat à l'aide de l'autorité de certification de test :
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 3650 \
-sha256 \
-extfile server.ext
Générez la clé privée du client :
openssl genrsa -out client.key.tmp 2048
Générez la CSR :
openssl req -new \
-key client.key.tmp \
-subj "/CN=Client-A" \
-out client.csr
Convertissez la clé privée au format PKCS#8 chiffré :
openssl pkcs8 \
-topk8 \
-in client.key.tmp \
-out client.key \
-v2 aes-256-cbc \
-passout pass:correct-password
La clé privée résultante est chiffrée avec :
correct-password
Créez les extensions du certificat client :
printf "extendedKeyUsage=clientAuth\n" \
> client.ext
Signez le certificat client :