summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2021-09-07 13:26:42 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-09-13 16:51:31 +0200
commit8ef147c43646e91fdaad5d0e7b60351f842e5c68 (patch)
tree61bc65da37b6c6e56a161c3ce841d15a4cc8b786 /lib
parent364f174724ef115c63d5e5dc1d3342c8a43b1cca (diff)
downloadcurl-8ef147c43646e91fdaad5d0e7b60351f842e5c68.tar.gz
ftp,imap,pop3,smtp: reject STARTTLS server response pipelining
If a server pipelines future responses within the STARTTLS response, the former are preserved in the pingpong cache across TLS negotiation and used as responses to the encrypted commands. This fix detects pipelined STARTTLS responses and rejects them with an error. CVE-2021-22947 Bug: https://curl.se/docs/CVE-2021-22947.html
Diffstat (limited to 'lib')
-rw-r--r--lib/ftp.c3
-rw-r--r--lib/imap.c4
-rw-r--r--lib/pop3.c4
-rw-r--r--lib/smtp.c4
4 files changed, 15 insertions, 0 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 08d18ca74..0b9c9b732 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2743,6 +2743,9 @@ static CURLcode ftp_statemachine(struct Curl_easy *data,
case FTP_AUTH:
/* we have gotten the response to a previous AUTH command */
+ if(pp->cache_size)
+ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */
+
/* RFC2228 (page 5) says:
*
* If the server is willing to accept the named security mechanism,
diff --git a/lib/imap.c b/lib/imap.c
index 923b1d59b..6163899bb 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -963,6 +963,10 @@ static CURLcode imap_state_starttls_resp(struct Curl_easy *data,
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(data->conn->proto.imapc.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(imapcode != IMAP_RESP_OK) {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied");
diff --git a/lib/pop3.c b/lib/pop3.c
index a331d71f7..d3f3de6d4 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -771,6 +771,10 @@ static CURLcode pop3_state_starttls_resp(struct Curl_easy *data,
CURLcode result = CURLE_OK;
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(data->conn->proto.pop3c.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(pop3code != '+') {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied");
diff --git a/lib/smtp.c b/lib/smtp.c
index 20dc85a5f..02ddaca0a 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -834,6 +834,10 @@ static CURLcode smtp_state_starttls_resp(struct Curl_easy *data,
CURLcode result = CURLE_OK;
(void)instate; /* no use for this yet */
+ /* Pipelining in response is forbidden. */
+ if(data->conn->proto.smtpc.pp.cache_size)
+ return CURLE_WEIRD_SERVER_REPLY;
+
if(smtpcode != 220) {
if(data->set.use_ssl != CURLUSESSL_TRY) {
failf(data, "STARTTLS denied, code %d", smtpcode);