CVE-2021-22946: Protocol downgrade required TLS bypassed
What the report claims
In imap and pop3, --ssl-reqd is silently ignored if the capability command failed, and in ftp a non-standard 230 response in the greeter message forces curl to continue unencrypted even if TLS has been required.
Compare with curl's recorded outcome
Known vulnerability
A real vulnerability: CVE-2021-22946 Protocol downgrade required TLS bypassed
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 known CVE (CVE-2021-22946) with specific reproduction steps targeting IMAP, POP3, and FTP protocols.
- The provided source code snippets do not include the relevant protocol implementation files (lib/imap.c, lib/pop3.c, lib/ftp.c) where the claimed flaws would exist.
- Deterministic checks returned 'nothing_to_check', confirming the relevant code was not found in the provided context.
- Without the protocol handling code, it is impossible to verify whether --ssl-reqd is ignored on capability failure (C1) or whether a 230 greeting bypasses TLS (C2).
- The report is plausible and specific, but the provided evidence is insufficient to confirm or refute the claims.
What still needs checking
- lib/imap.c - IMAP protocol handling, especially CAPABILITY command response processing and ssl_reqd logic
- lib/pop3.c - POP3 protocol handling, especially CAPA command response processing and ssl_reqd logic
- lib/ftp.c - FTP protocol handling, especially server greeting response parsing (code 230) and ftp_ssl_control logic
How this analysis ran 5 claims · 0 citations verified
Checked against curl master on 2021-09-09 (71f9a8fa6f52). Test 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. To assess the claims, we need the IMAP, POP3, and FTP protocol implementation files (lib/imap.c, lib/pop3.c, lib/ftp.c) from the revision you tested (71f9a8fa6f52). The provided source snippets only show header files and do not contain the protocol logic that handles CAPABILITY/CAPA responses, FTP greeting codes, or the --ssl-reqd/--ftp-ssl-control options. Could you point to the specific functions and lines in those files where the TLS requirement check is skipped?
Inspect all claims and source code 5 claims · 2 code excerpts
Report claims
In imap and pop3, --ssl-reqd is silently ignored if the capability command failed.
Read the reasoning
The claim concerns IMAP and POP3 protocol handling when the CAPABILITY/CAPA command fails. The provided source code only shows lib/urldata.h (CURLcode typedef and includes) and include/curl/curl.h (CURLOPT_FTP_SSL define). The actual IMAP (lib/imap.c) and POP3 (lib/pop3.c) protocol implementation files are not included, so the code paths that handle capability command responses and CURLOPT_SSL_REQUIRED cannot be examined.
In ftp, a non-standard 230 response (preauthentication?) in the greeter message forces curl to continue unencrypted, even if TLS has been required.
Read the reasoning
The claim concerns FTP protocol handling of a 230 response in the server greeting. The provided source code does not include lib/ftp.c where the FTP protocol is implemented. Only CURLOPT_FTP_SSL define is shown. The code that parses the FTP greeting response and decides whether to proceed with TLS negotiation is not available for review.
Use a parameterizable test server to fail capability command for imap (CAPABILITY reply: A001 BAD Not implemented) and pop3 (CAPA reply: -ERR Not implemented) and to send response code 230 in FTP server greeting message.
Read the reasoning
This claim describes attack trigger conditions (specific server responses). It is not a claim about curl's code behavior that can be verified from source code alone; it describes the attacker's setup.
A MitM can silently deny mandatory TLS negotiation and thus sniff and/or update unencrypted transferred data.
Read the reasoning
This claim describes the security impact (MitM can sniff/modify data). Impact claims require verifying the underlying code flaws (C1, C2) first, which are not_verifiable with the provided code.
curl --ssl-reqd imap://server/...; curl --ssl-reqd pop3://server/...; curl --ssl-reqd --ftp-ssl-control ftp://server/...
Read the reasoning
This claim provides reproduction commands. It cannot be verified from static source code alone; it requires a test environment.
What the report says about other projects
not addressed The FTP 230 response code indicates successful authentication but does not guarantee that the connection is encrypted.
Read the original report
Source code
| 122 | typedef CURLcode (*Curl_datastream)(struct Curl_easy *data, |
| 123 | struct connectdata *conn, |
| 124 | int *didwhat, |
| 125 | bool *done, |
| 126 | int select_res); |
| 127 | #endif |
| 128 | |
| 129 | #include "mime.h" |
| 130 | #include "imap.h" |
| 131 | #include "pop3.h" |
| 132 | #include "smtp.h" |
| 133 | #include "ftp.h" |
| 134 | #include "file.h" |
| 135 | #include "vssh/ssh.h" |
| 136 | #include "http.h" |
| 137 | #include "rtsp.h" |
| 138 | #include "smb.h" |
| 139 | #include "mqtt.h" |
| 140 | #include "wildcard.h" |
| 141 | #include "multihandle.h" |
| 142 | #include "quic.h" |
| 143 | #include "c-hyper.h" |
| 144 | |
| 145 | #ifdef HAVE_GSSAPI |
| 146 | # ifdef HAVE_GSSGNU |
| 147 | # include <gss.h> |
| 148 | # elif defined HAVE_GSSAPI_GSSAPI_H |
| 149 | # include <gssapi/gssapi.h> |
| 150 | # else |
| 151 | # include <gssapi.h> |
| 152 | # endif |
| 153 | # ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H |
| 154 | # include <gssapi/gssapi_generic.h> |
| 155 | # endif |
| 156 | #endif |
| 157 | |
| 158 | #ifdef HAVE_LIBSSH2_H |
| 159 | #include <libssh2.h> |
| 160 | #include <libssh2_sftp.h> |
| 161 | #endif /* HAVE_LIBSSH2_H */ |
| 162 | |
| 163 | #define READBUFFER_SIZE CURL_MAX_WRITE_SIZE |
| 164 | #define READBUFFER_MAX CURL_MAX_READ_SIZE |
| 165 | #define READBUFFER_MIN 1024 |
| 166 | |
| 167 | /* The default upload buffer size, should not be smaller than |
| 168 | CURL_MAX_WRITE_SIZE, as it needs to hold a full buffer as could be sent in |
| 169 | a write callback. |
| 170 | |
| 171 | The size was 16KB for many years but was bumped to 64KB because it makes |
| 172 | libcurl able to do significantly faster uploads in some circumstances. Even |
| 173 | larger buffers can help further, but this is deemed a fair memory/speed |
| 174 | compromise. */ |
| 175 | #define UPLOADBUFFER_DEFAULT 65536 |
| 176 | #define UPLOADBUFFER_MAX (2*1024*1024) |
| 177 | #define UPLOADBUFFER_MIN CURL_MAX_WRITE_SIZE |
| 178 | |
| 179 | #define CURLEASY_MAGIC_NUMBER 0xc0dedbadU |
| 180 | #define GOOD_EASY_HANDLE(x) \ |
| 181 | ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) |
| 182 | |
| 183 | /* the type we use for storing a single boolean bit */ |
| 184 | #ifdef _MSC_VER |
| 185 | typedef bool bit; |
| 186 | #define BIT(x) bool x |
| 187 | #else |
| 188 | typedef unsigned int bit; |
| 189 | #define BIT(x) bit x:1 |
| 190 | #endif |
| 191 | |
| 192 | #ifdef HAVE_GSSAPI |
| 193 | /* Types needed for krb5-ftp connections */ |
| 194 | struct krb5buffer { |
| 195 | void *data; |
| 196 | size_t size; |
| 197 | size_t index; |
| 198 | BIT(eof_flag); |
| 199 | }; |
| 2123 | #define CURLOPT_FTP_SSL CURLOPT_USE_SSL |