
Proof-of-Concept zur Reproduktion von CVE-2026-8932, einer Schwachstelle durch unvollständige mTLS-Konfigurationsübereinstimmung bei der Verbindungswiederverwendung in libcurl, mit einem lokalen Lab-Server und einem C-PoC.
Proof-of-Concept-Reproduktion von CVE-2026-8932, einem Problem bei der unvollständigen Übereinstimmung der mTLS-Konfiguration in der Verbindungswiederverwendung von libcurl.
CVE-2026-8932 betrifft die Logik zur Verbindungswiederverwendung von libcurl, wenn sich die Mutual-TLS-Konfiguration (mTLS) zwischen Anfragen ändert.
Unter anfälligen Bedingungen kann libcurl eine bestehende TLS-Verbindung wiederverwenden, obwohl sich eine mTLS-bezogene Konfigurationsoption geändert hat und dies eine Wiederverwendung dieser Verbindung hätte verhindern müssen.
Dieses PoC demonstriert das Problem, indem das Passwort für den privaten Schlüssel zwischen zwei Anfragen geändert wird, während dasselbe Client-Zertifikat und derselbe private Schlüssel verwendet werden.
Die erste Anfrage verwendet das korrekte Passwort:
correct-password
Die zweite Anfrage verwendet absichtlich ein ungültiges Passwort:
WRONG-PASSWORD
Wenn libcurl die bestehende TLS-Verbindung fälschlicherweise wiederverwendet, erfordert die zweite Anfrage keinen weiteren TLS-Handshake. Folglich wird das ungültige Private-Key-Passwort nie benötigt, um eine neue TLS-Verbindung aufzubauen, und die Anfrage ist erfolgreich.
Das PoC demonstriert somit die Bedingung der Verbindungswiederverwendung im Zusammenhang mit CVE-2026-8932.
| Eigenschaft | Wert |
|---|---|
| CVE | CVE-2026-8932 |
| Komponente | libcurl |
| Schwachstellentyp | Unvollständiger Abgleich der mTLS-Konfiguration |
| CWE | CWE-305 — Authentifizierungsumgehung durch primäre Schwäche |
| Betroffener Bereich | TLS-Verbindungswiederverwendung |
| Protokoll | HTTPS / mTLS |
| Client | libcurl API |
| curl CLI | Nicht betroffen |
| PoC-Umfang | Lokale Laborumgebung |
Die Schwachstelle ist ein Problem beim Abgleich von Logik/Konfiguration und keine traditionelle Speichersicherheits-Schwachstelle wie ein Pufferüberlauf oder Use-after-free.
libcurl verwaltet Verbindungsinformationen und kann eine bestehende Verbindung wiederverwenden, wenn eine nachfolgende Anfrage als mit der Konfiguration der Verbindung kompatibel angesehen wird.
Für TLS-Verbindungen muss die Verbindungskonfiguration daher vor der Wiederverwendung sorgfältig verglichen werden.
Die verwundbare Implementierung bezog nicht alle relevanten mTLS-Konfigurationsfelder in die Logik für den Verbindungsabgleich ein.
Zu den betroffenen Einstellungen gehören:
cert_type
key
key_type
key_passwd
key_blob
Die in diesem PoC verwendete wichtige Einstellung ist:
key_passwd
Das PoC stellt eine TLS-Verbindung unter Verwendung eines verschlüsselten privaten Client-Schlüssels und des korrekten Passworts her:
correct-password
Anschließend führt es eine weitere Anfrage mit demselben Zertifikat und Schlüssel aus, ändert jedoch das Passwort auf:
WRONG-PASSWORD
Eine anfällige Implementierung der Verbindungszuordnung kann die bestehende Verbindung dennoch als wiederverwendbar betrachten.
Der Test besteht aus zwei HTTP-Anfragen.
Die erste Anfrage stellt die TLS-Verbindung her:
URL:
https://server.test:8443/A
Client certificate:
client.crt
Private key:
client.key
Key password:
correct-password
Die TLS-Verbindung bleibt bestehen, da der Server HTTP Keep-Alive unterstützt.
Die zweite Anfrage verwendet dasselbe Zertifikat und denselben privaten Schlüssel, ändert jedoch das Schlüsselkennwort:
URL:
https://server.test:8443/B
Client certificate:
client.crt
Private key:
client.key
Key password:
WRONG-PASSWORD
Wenn libcurl eine neue TLS-Verbindung aufbaut, sollte das Laden des verschlüsselten privaten Schlüssels mit dem falschen Passwort fehlschlagen.
Wenn libcurl jedoch fälschlicherweise die bestehende Verbindung wiederverwendet, ist kein neuer TLS-Handshake erforderlich.
Das ungültige Passwort verhindert daher nicht, dass die HTTP-Anfrage erfolgreich ist.
Der Laboraufbau besteht aus:
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)
Die wichtige Beobachtung ist, dass /A und /B auf derselben TLS-Verbindung ankommen müssen.
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
Das Verzeichnis certs/ wird im Repository absichtlich leer gehalten. Zertifikate und private Schlüssel sollten lokal generiert werden.
Das PoC wurde in der folgenden Umgebung getestet:
OS:
Debian GNU/Linux 13 (trixie)
Architecture:
x86_64
libcurl:
8.14.1
OpenSSL:
3.5.7
GCC:
14.2.0
Die für die Reproduktion verwendete verwundbare libcurl-Installation war:
libcurl/8.14.1
Überprüfen Sie die installierte Version:
curl --version
und:
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
Generieren Sie den privaten Serverschlüssel:
openssl genrsa -out server.key 2048
Generieren Sie die CSR:
openssl req -new \
-key server.key \
-subj "/CN=server.test" \
-out server.csr
Erstellen Sie die Zertifikatserweiterungen:
printf "subjectAltName=DNS:server.test\nextendedKeyUsage=serverAuth\n" \
> server.ext
Signieren Sie das Zertifikat mit der Test-CA:
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 3650 \
-sha256 \
-extfile server.ext
Generieren Sie den privaten Schlüssel des Clients:
openssl genrsa -out client.key.tmp 2048
Generieren Sie die CSR:
openssl req -new \
-key client.key.tmp \
-subj "/CN=Client-A" \
-out client.csr
Konvertieren Sie den privaten Schlüssel in das verschlüsselte PKCS#8-Format:
openssl pkcs8 \
-topk8 \
-in client.key.tmp \
-out client.key \
-v2 aes-256-cbc \
-passout pass:correct-password
Der resultierende private Schlüssel wird verschlüsselt mit:
correct-password
Erstellen Sie die Client-Zertifikatserweiterungen:
printf "extendedKeyUsage=clientAuth\n" \
> client.ext