HexBrain

curl · Report #3973190

CVE-2026-86411: FTP connection reuse inherits client-certificate

Validstatus
1upvotes
14 Oct 2026disclosed

How it was found

Summary

An ftp:// transfer configured with CURLUSESSL_NONE can reuse a pooled FTP control connection that a previous easy handle upgraded with STARTTLS and authenticated using a client certificate. The second handle performs neither a new TLS handshake nor a new FTP login, so the server continues to authorize it under the first handle's certificate identity.

This is a regression introduced in commit 4ff212f8ed328fb95261e11add8f4d2f0616895a ("url: connection reuse fixes for starttls"). It is closely related to CVE-2016-5420 (client-certificate identity reuse across connections).

Root cause

Three things combine to allow this:

  1. FTP declares PROTOPT_SSL_REUSE (lib/protocol.c), so url_match_ssl_use() (lib/url.c:712-730) accepts an existing TLS-upgraded connection for a later plain ftp:// transfer.

  2. For CURLUSESSL_NONE, connection matching sets may_tls = false and require_tls = false (lib/url.c:1187-1188). url_match_ssl_config() (lib/url.c:883-895) only calls Curl_ssl_conn_config_match() when PROTOPT_SSL is set or may_tls is true. Neither condition holds, so the client-certificate configuration is never compared.

  3. Commit 4ff212f8ed changed Curl_ftp_conns_match() (lib/ftp.c:4472-4492) from exact use_ssl equality (!=) to rejecting only when the new value is greater than the pooled connection's value (>). This permits the CURLUSESSL_CONTROL -> CURLUSESSL_NONE direction.

Impact

A handle configured with no client certificate silently inherits the TLS session and certificate identity of a previous handle that used the same connection pool, same FTP destination, and same FTP credentials. The second handle can then perform operations that the server authorizes based on the first handle's certificate.

Prerequisites:

  1. Two handles share a connection pool and target the same FTP server with the same USER/PASS.
  2. The first handle uses CURLUSESSL_CONTROL with a privileged client certificate.
  3. The second handle uses CURLUSESSL_NONE with no client certificate.
  4. The FTP server derives authorization from the TLS client certificate.

I consider this Low severity given the narrow prerequisites, but the result is a cross-handle authentication bypass, not merely stronger-than-requested encryption.

Affected versions

curl 8.21.0, plus affected 8.22.0 prerelease/development versions. Introduced by 4ff212f8ed.

Reproduction

  1. Build curl 8.21.0 or another affected revision with FTP, explicit TLS, and client-certificate support.
  2. Create a test CA, an FTP server certificate, a privileged client certificate, and a separate unprivileged client certificate.
  3. Start an FTP server that supports AUTH TLS, requests client certificates, and records a stable identifier and client-certificate identity for each control connection.
  4. Configure one FTP resource or command to succeed only when the control connection presents the privileged client certificate.
  5. Use the same ordinary FTP username and password for both privileged and unprivileged test transfers so that the authorization difference comes only from the TLS client identity.
  6. Create one libcurl multi handle that will provide a shared connection pool.
  7. Create a first easy handle for the protected FTP resource, set CURLOPT_USE_SSL to CURLUSESSL_CONTROL, configure the privileged certificate and key, and add it to the multi handle.
  8. Perform the first transfer and confirm that it succeeds, the server records the privileged certificate identity, and curl leaves the FTP control connection available for reuse.
  9. Remove the first easy handle while retaining the multi handle and its connection pool.
  10. Create a second easy handle for the same FTP destination using the same FTP username and password, but set CURLOPT_USE_SSL to CURLUSESSL_NONE and configure no client certificate.
  11. Perform the second transfer and record CURLINFO_NUM_CONNECTS, the FTP response, the underlying server connection identifier, and the certificate identity associated with the request.
  12. Observe the vulnerable result: the second transfer reuses the first TLS-upgraded control connection, opens no new control connection, and accesses the protected resource under the privileged certificate identity.
  13. Repeat the second transfer with CURLOPT_FRESH_CONNECT enabled.
  14. Confirm that a new control connection is created without a client certificate and the server denies access.
  15. Repeat using explicit TLS and the unprivileged certificate on the second handle.
  16. Confirm that curl creates a connection with the unprivileged identity and the server denies access.
  17. As a positive control, repeat with the same privileged certificate on both handles and confirm that reuse and authorization are expected.
  18. Confirm a fix by requiring client-identity configuration compatibility whenever the pooled connection already uses TLS, even when the new transfer itself specifies CURLUSESSL_NONE.
  19. Repeat the original privileged-then-no-certificate sequence and verify that the second handle does not inherit the first handle's authenticated FTP control connection.

Expected result

A transfer without a client certificate must not reuse a control connection authenticated with another handle's client certificate. It must establish its own connection and receive only its own authorization.

Vulnerable result

Curl permits a weaker FTP configuration to reuse the existing TLS control connection without comparing client-certificate settings. The later handle inherits the earlier handle's privileged certificate identity and authenticated FTP session.

Suggested fix

When an existing connection has TLS (via STARTTLS), compare client-certificate configuration even when the new handle does not itself request TLS (may_tls = false). At minimum, url_match_ssl_config() should also gate on whether the pooled connection already has TLS, not only on whether the new handle wants TLS.

Impact

Summary:

A lower-privileged transfer sharing curl’s connection pool can operate under a previous handle’s authenticated client-certificate identity. If the FTP server grants additional permissions based on that certificate, the later transfer may read, upload, modify, or delete resources it could not access using its own configuration, creating a cross-handle authorization bypass.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original