CVE-2020-8231: Connect-only connections can use the wrong connection
What the report claims
A connect-only easy handle may reuse a connection address after the original connection times out, causing data intended for the original server to be sent to a different server.
Compare with curl's recorded outcome
Known vulnerability
A real vulnerability: CVE-2020-8231 wrong connect-only connection
Shown for comparison after analysis. The pipeline did not see this label.
ProveIt's finding
The available evidence does not settle the report. A maintainer should investigate.
Why this finding?
- The report describes a plausible use-after-free / pointer-reuse flaw in connect-only connection handling with a concrete reproducer.
- The provided curl source snippets (curl_multi_socket_action, curl_easy_send) are only entry points; the deciding connection management code (easy_connection, connection pool, connect-only association, CURLOPT_MAXAGE_CONN expiration) is not included.
- All five claims are not_verifiable against the provided code. A human must examine the connection management logic in lib/url.c, lib/conncache.c, lib/easy.c (easy_connection), and multi.c (multi_socket) at the target revision.
What still needs checking
- The easy_connection function implementation
- Connection cache/pool management code (likely in lib/conncache.c)
- How connect-only handles store and retrieve their connection pointer
- CURLOPT_MAXAGE_CONN expiration handling and connection cleanup
How this analysis ran 5 claims · 0 citations verified
Checked against curl master on 2020-07-31 (633c9478c91f). Dev evaluation split. Citation verification checks that a referenced line was in the evidence; it does not prove the model interpreted it correctly.
Review a draft reply to the reporter
Edit and verify before sending.
Thank you for the detailed report and reproducer. The issue you describe (connect-only handle reusing a freed connection's address after CURLOPT_MAXAGE_CONN timeout) is plausible and the custom allocator is a clever way to force deterministic reuse. However, the source snippets we have (curl_multi_socket_action, curl_easy_send) don't include the connection management logic that would confirm or deny the flaw. Could you point to the specific functions/files where connect-only handles track their connection (e.g., easy_connection, connection cache, CURLOPT_MAXAGE_CONN handling)? That would let us verify the fix.
Inspect all claims and source code 5 claims · 2 code excerpts
Report claims
A connect-only easy handle can reuse a connection address after the original connection times out, leading to data being sent to the wrong server.
Read the reasoning
The claim describes a connection reuse flaw in connect-only handles after timeout. The provided source snippets only show curl_multi_socket_action and curl_easy_send entry points. The critical connection management logic (easy_connection function, connection pool, connect-only handle association, CURLOPT_MAXAGE_CONN handling) is not in the provided code. Cannot verify or contradict from given source.
The issue occurs in the curl multi socket action handling of connect-only handles.
Read the reasoning
The claim locates the issue in curl_multi_socket_action handling of connect-only handles. The provided curl_multi_socket_action (lib/multi.c:2991-3001) only shows a thin wrapper calling multi_socket. The actual connection timeout and reuse logic would be in multi_socket or connection management code, which is not provided.
When a connection times out and is closed, a new connection may be allocated at the same address and reused by a connect-only handle.
Read the reasoning
The claim describes the trigger mechanism: connection timeout, close, reallocation at same address, reuse by connect-only handle. The reporter's custom allocator (malloc_/free_) demonstrates deterministic address reuse, but curl's actual connection allocation/free logic and how connect-only handles track connections is not in the provided source.
Sensitive data intended for one server may be transmitted to a different server.
Read the reasoning
The impact claim follows from C1-C3. curl_easy_send (lib/easy.c:1145-1173) calls easy_connection to get the connection, but easy_connection is not provided. Without seeing how the connection pointer is stored and validated, cannot confirm data would go to the wrong server.
The provided sample program demonstrates deterministic address reuse causing data to be sent to port 1236 instead of port 1234.
Read the reasoning
The reproduction program is provided in the report and uses a custom caching allocator to force address reuse. Whether this actually triggers the described flaw in curl depends on curl's internal connection management, which is not in the provided source snippets.
Read the original report (excerpt)
Source code
| 2991 | CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s, |
| 2992 | int ev_bitmask, int *running_handles) |
| 2993 | { |
| 2994 | CURLMcode result; |
| 2995 | if(multi->in_callback) |
| 2996 | return CURLM_RECURSIVE_API_CALL; |
| 2997 | result = multi_socket(multi, FALSE, s, ev_bitmask, running_handles); |
| 2998 | if(CURLM_OK >= result) |
| 2999 | Curl_update_timer(multi); |
| 3000 | return result; |
| 3001 | } |
| 1145 | CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer, |
| 1146 | size_t buflen, size_t *n) |
| 1147 | { |
| 1148 | curl_socket_t sfd; |
| 1149 | CURLcode result; |
| 1150 | ssize_t n1; |
| 1151 | struct connectdata *c = NULL; |
| 1152 | |
| 1153 | if(Curl_is_in_callback(data)) |
| 1154 | return CURLE_RECURSIVE_API_CALL; |
| 1155 | |
| 1156 | result = easy_connection(data, &sfd, &c); |
| 1157 | if(result) |
| 1158 | return result; |
| 1159 | |
| 1160 | *n = 0; |
| 1161 | result = Curl_write(c, sfd, buffer, buflen, &n1); |
| 1162 | |
| 1163 | if(n1 == -1) |
| 1164 | return CURLE_SEND_ERROR; |
| 1165 | |
| 1166 | /* detect EAGAIN */ |
| 1167 | if(!result && !n1) |
| 1168 | return CURLE_AGAIN; |
| 1169 | |
| 1170 | *n = (size_t)n1; |
| 1171 | |
| 1172 | return result; |
| 1173 | } |