ignoring 'options' when doing connection reuse

Disclosed: 2026-04-05 21:00:59 By spichanlio76 To curl
Unknown
Vulnerability Details
libcurl contains a significant logic flaw in its connection pool matching mechanism. When a transfer specifies a required authentication policy—such as a specific SASL mechanism (e.g., `;AUTH=GSSAPI`) or a restricted set of SSH authentication types (`CURLOPT_SSH_AUTH_TYPES`)—libcurl fails to verify these constraints against existing connections in its pool. This leads to a **Silent Policy Bypass**: a transfer requesting a high-security authentication method will incorrectly reuse a pooled connection established with a different (and potentially weaker) method, provided the basic credentials (username/password) match. The developer's explicit security instructions are discarded, and the transfer proceeds under the security context of a previous, different authentication state without any warning. Technical Description The vulnerability exists in the connection matching logic in `lib/url.c`. Libcurl maintains a pool of connections and attempts to reuse them to improve performance. To ensure security, it must verify that the new request's security requirements match the properties of the cached connection. 1. SASL Mechanism Bypass (IMAP, SMTP, POP3, LDAP) In SASL-enabled protocols, users can specify a required authentication mechanism via the URL (e.g., `imap://user:pass;AUTH=GSSAPI@host/`) or the `CURLOPT_LOGIN_OPTIONS` setting. This string is stored in the connection's `options` field. However, the primary authentication matcher, `url_match_auth()`, **completely ignores** the `options` field. It only compares the `user`, `passwd`, `sasl_authzid`, and `oauth_bearer`. **Vulnerable Code (**[lib/url.c:1023](file:///d:/curl/lib/url.c#L1023)**):** ```c static bool url_match_auth(struct connectdata *conn, struct url_conn_match *m) { if(!(m->needle->scheme->flags & PROTOPT_CREDSPERREQUEST)) { if(Curl_timestrcmp(m->needle->user, conn->user) || Curl_timestrcmp(m->needle->passwd, conn->passwd) || Curl_timestrcmp(m->needle->sasl_authzid, conn->sasl_authzid) || Curl_timestrcmp(m->needle->oauth_bearer, conn->oauth_bearer)) { return FALSE; } // ERROR: conn->options (the AUTH mechanism string) is NEVER compared! } return TRUE; } ``` 2. SSH Authentication Type Bypass (SFTP, SCP) Similarly, for SSH protocols, the user can restrict allowed authentication methods via `CURLOPT_SSH_AUTH_TYPES` (e.g., forcing Public Key only and forbidding Passwords). The SSH matching function `ssh_config_matches()` verifies host keys but **fails to verify the handle's authentication policy**. **Vulnerable Code (**[lib/url.c:705](file:///d:/curl/lib/url.c#L705)**):** ```c static bool ssh_config_matches(struct Curl_easy *data, ...) { // ... host key checks ... // ERROR: data->set.ssh_auth_types (the security constraint bitmask) is NEVER checked! return TRUE; } ``` ## Steps to Reproduce This example uses the IMAP protocol, but the impact is identical across SMTP, POP3, SFTP, and SCP. 1. **Step 1**: Initialize a shared connection pool (`CURLSH`). 2. **Step 2 (The Poison Request)**: Perform a transfer to an IMAP server using a weak authentication mechanism: `imap://privileged_user:secret;[email protected]/` The connection is established, authenticated via PLAIN, and added to the pool. 3. **Step 3 (The Secure Request)**: Another part of the application (or a different tenant in a shared service) performs a transfer requiring a high-security mechanism: `imap://privileged_user:secret;[email protected]/` (The developer *intends* for this to only proceed if Kerberos/GSSAPI is used). 4. **Step 4 (The Bypass)**: libcurl's matching logic sees that the `user` and `pass` are the same. It **ignores** the requested `AUTH=GSSAPI` constraint and reuses the existing PLAIN connection. **Result**: Transfer 2 succeeds over a session established with a different security policy than requested. No GSSAPI authentication is performed. --- ## Impact 1. Security Policy Bypass Developers use `AUTH=mechanism` and `SSH_AUTH_TYPES` as explicit security controls. If a developer disables a weak authentication method to meet compliance or security requirements, libcurl **silently violates** that constraint by reusing connections that utilized the forbidden method. 2. Confidentiality & Authentication Strength Downgrade In multi-tenant environments (proxies, shared backends), one tenant can "prime" the connection pool with a weak authentication state, which is then inherited by a high-security handle belonging to another tenant. This allows for lateral movement and elevation of authentication state without the required cryptographic proofs (e.g. Kerberos tickets). 3. Identity Leakage Because the authentication *state* is tied to the connection, reusing a connection established with one set of options for a handle requesting another leads to a breach of isolation between independent security contexts. Recommended Mitigation 1. **Update url_match_auth**: Add a mandatory string comparison for the `options` field. ```c if(Curl_timestrcmp(m->needle->options, conn->options)) return FALSE; ``` 2. **Update ssh_config_matches**: Ensure the pooled connection's established authentication method is compatible with the new handle's `ssh_auth_types` bitmask. Supporting Evidence - **Source Proof**: [lib/url.c:1023](file:///d:/curl/lib/url.c#L1023) and [lib/url.c:705](file:///d:/curl/lib/url.c#L705) - **Impact Protocol Audit**: IMAP, SMTP, POP3, LDAP, SFTP, SCP all share this vulnerability.
Actions
View on HackerOne
Report Stats
  • Report ID: 3646914
  • State: Closed
  • Substate: informative
Share this report