
Prova de conceito que reproduz o CVE-2026-8932, uma falha de correspondência em configuração mTLS incompleta na reutilização de conexões do libcurl, com um servidor de laboratório local e PoC em C.
Reprodução de prova de conceito da CVE-2026-8932, uma falha de correspondência em configuração mTLS incompleta na reutilização de conexões do libcurl.
A CVE-2026-8932 afeta a lógica de reutilização de conexões do libcurl quando a configuração de mutual TLS (mTLS) muda entre requisições.
Em condições vulneráveis, o libcurl pode reutilizar uma conexão TLS existente mesmo que uma opção de configuração relacionada a mTLS tenha mudado e deveria ter impedido a reutilização dessa conexão.
Esta PoC demonstra o problema alterando a senha da chave privada entre duas requisições, enquanto se utiliza o mesmo certificado de cliente e a mesma chave privada.
A primeira requisição usa a senha correta:
correct-password
A segunda solicitação usa intencionalmente uma senha inválida:
WRONG-PASSWORD
Se o libcurl reutilizar incorretamente a conexão TLS existente, a segunda requisição não exigirá outro handshake TLS. Consequentemente, a senha inválida da chave privada nunca será necessária para estabelecer uma nova conexão TLS e a requisição será bem-sucedida.
O PoC, portanto, demonstra a condição de reutilização de conexão associada à CVE-2026-8932.
| Propriedade | Valor |
|---|---|
| CVE | CVE-2026-8932 |
| Componente | libcurl |
| Tipo de Vulnerabilidade | Correspondência incompleta de configuração mTLS |
| CWE | CWE-305 — Authentication Bypass by Primary Weakness |
| Área Afetada | Reutilização de conexão TLS |
| Protocolo | HTTPS / mTLS |
| Cliente | API libcurl |
| CLI curl | Não afetado |
| Escopo do PoC | Ambiente de laboratório local |
A vulnerabilidade é um problema de correspondência de lógica/configuração, e não uma vulnerabilidade tradicional de segurança de memória, como um buffer overflow ou use-after-free.
O libcurl mantém informações de conexão e pode reutilizar uma conexão existente quando uma requisição subsequente é considerada compatível com a configuração da conexão.
Para conexões TLS, a configuração da conexão deve, portanto, ser comparada cuidadosamente antes da reutilização.
A implementação vulnerável não incluía todos os campos relevantes de configuração mTLS na lógica de correspondência de conexão.
Entre as configurações afetadas estão:
cert_type
key
key_type
key_passwd
key_blob
A configuração importante usada por este PoC é:
key_passwd
O PoC estabelece uma conexão TLS usando uma chave privada de cliente criptografada e a senha correta:
correct-password
Em seguida, realiza outra requisição usando o mesmo certificado e chave, mas altera a senha para:
WRONG-PASSWORD
Uma implementação vulnerável de correspondência de conexões ainda pode considerar a conexão existente reutilizável.
O teste consiste em duas requisições HTTP.
A primeira requisição estabelece a conexão TLS:
URL:
https://server.test:8443/A
Client certificate:
client.crt
Private key:
client.key
Key password:
correct-password
A conexão TLS permanece persistente porque o servidor suporta HTTP keep-alive.
A segunda requisição usa o mesmo certificado e chave privada, mas altera a senha da chave:
URL:
https://server.test:8443/B
Client certificate:
client.crt
Private key:
client.key
Key password:
WRONG-PASSWORD
Se o libcurl criar uma nova conexão TLS, o carregamento da chave privada criptografada com a senha errada deve falhar.
No entanto, se o libcurl reutilizar incorretamente a conexão existente, nenhum novo handshake TLS será necessário.
Portanto, a senha inválida não impede que a requisição HTTP seja bem-sucedida.
A configuração do laboratório consiste em:
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)
A observação importante é que /A e /B devem chegar na mesma conexão 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
O diretório certs/ é intencionalmente mantido vazio no repositório. Certificados e chaves privadas devem ser gerados localmente.
O PoC foi testado no seguinte ambiente:
OS:
Debian GNU/Linux 13 (trixie)
Architecture:
x86_64
libcurl:
8.14.1
OpenSSL:
3.5.7
GCC:
14.2.0
A instalação vulnerável do libcurl usada para a reprodução foi:
libcurl/8.14.1
Verifique a versão instalada:
curl --version
e:
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
Gere a chave privada do servidor:
openssl genrsa -out server.key 2048
Gere o CSR:
openssl req -new \
-key server.key \
-subj "/CN=server.test" \
-out server.csr
Crie as extensões do certificado:
printf "subjectAltName=DNS:server.test\nextendedKeyUsage=serverAuth\n" \
> server.ext
Assine o certificado usando a CA de teste:
openssl x509 -req \
-in server.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out server.crt \
-days 3650 \
-sha256 \
-extfile server.ext
Gere a chave privada do cliente:
openssl genrsa -out client.key.tmp 2048
Gere o CSR:
openssl req -new \
-key client.key.tmp \
-subj "/CN=Client-A" \
-out client.csr
Converta a chave privada para o formato PKCS#8 criptografado:
openssl pkcs8 \
-topk8 \
-in client.key.tmp \
-out client.key \
-v2 aes-256-cbc \
-passout pass:correct-password
A chave privada resultante é criptografada com:
correct-password
Crie as extensões do certificado do cliente:
printf "extendedKeyUsage=clientAuth\n" \
> client.ext
Assine o certificado do cliente:
openssl x509 -req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-out client.crt \
-days 3650 \
-sha256 \
-extfile client.ext
Neste ponto, os arquivos necessários devem existir:
certs/
├── ca.crt
├── ca.key
├── client.crt
├── client.key
├── server.crt
└── server.key
Entre no diretório do servidor:
cd ~/cve-2026-8932-lab/server