diff --git a/lib/creds.c b/lib/creds.c index a11816ca54..b24b8af24c 100644 --- a/lib/creds.c +++ b/lib/creds.c @@ -46,6 +46,7 @@ CURLcode Curl_creds_create(const char *user, size_t salen = sasl_authzid ? strlen(sasl_authzid) : 0; size_t sslen = sasl_service ? strlen(sasl_service) : 0; char *s, *buf; + size_t bufsize; CURLcode result = CURLE_OK; Curl_creds_unlink(pcreds); @@ -64,13 +65,14 @@ CURLcode Curl_creds_create(const char *user, } /* null-terminator for user already part of struct */ - creds = curlx_calloc(1, sizeof(*creds) + - ulen + plen + 1 + olen + 1 + salen + 1 + sslen + 1); + bufsize = ulen + plen + 1 + olen + 1 + salen + 1 + sslen + 1; + creds = curlx_calloc(1, sizeof(*creds) + bufsize); if(!creds) { result = CURLE_OUT_OF_MEMORY; goto out; } + creds->bufsize = bufsize; creds->refcount = 1; creds->source = source; /* Some compilers try to be too smart about our dynamic struct size */ @@ -144,6 +146,7 @@ void Curl_creds_unlink(struct Curl_creds **pcreds) if(creds->refcount) creds->refcount--; if(!creds->refcount) { + curlx_memzero(creds, sizeof(*creds) + creds->bufsize); curlx_free(creds); } } diff --git a/lib/creds.h b/lib/creds.h index 36deff323e..8b14cad719 100644 --- a/lib/creds.h +++ b/lib/creds.h @@ -39,6 +39,7 @@ struct Curl_creds { const char *sasl_service; /* non-NULL, maybe empty string */ uint32_t refcount; uint8_t source; /* CREDS_* value */ + size_t bufsize; /* extra bytes added to sizeof(struct Curl_creds) */ char buf[1]; }; diff --git a/lib/curl_sspi.c b/lib/curl_sspi.c index 3ea17621b1..c733892d86 100644 --- a/lib/curl_sspi.c +++ b/lib/curl_sspi.c @@ -100,6 +100,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, xcharp_u domain, dup_domain; xcharp_u passwd, dup_passwd; size_t domlen = 0; + size_t pwlen; domain.const_tchar_ptr = TEXT(""); @@ -155,17 +156,20 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, curlx_free(dup_domain.tchar_ptr); return CURLE_OUT_OF_MEMORY; } + pwlen = _tcslen(passwd.tchar_ptr); dup_passwd.tchar_ptr = curlx_tcsdup(passwd.tchar_ptr); if(!dup_passwd.tchar_ptr) { curlx_free(dup_user.tchar_ptr); curlx_free(dup_domain.tchar_ptr); + curlx_memzero(passwd.tchar_ptr, pwlen * sizeof(*passwd.tchar_ptr)); curlx_free(passwd.tchar_ptr); return CURLE_OUT_OF_MEMORY; } identity->Password = dup_passwd.tbyte_ptr; - identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); + identity->PasswordLength = curlx_uztoul(pwlen); dup_passwd.tchar_ptr = NULL; + curlx_memzero(passwd.tchar_ptr, pwlen * sizeof(*passwd.tchar_ptr)); curlx_free(passwd.tchar_ptr); identity->User = dup_user.tbyte_ptr; @@ -199,6 +203,8 @@ void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity) { if(identity) { curlx_safefree(identity->User); + curlx_memzero(identity->Password, + identity->PasswordLength * sizeof(*identity->Password)); curlx_safefree(identity->Password); curlx_safefree(identity->Domain); } diff --git a/lib/imap.c b/lib/imap.c index fc3077985d..5c1229193b 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -613,6 +613,7 @@ static CURLcode imap_perform_login(struct Curl_easy *data, passwd ? passwd : ""); curlx_free(user); + curlx_strzero(passwd); curlx_free(passwd); if(!result) diff --git a/lib/mqtt.c b/lib/mqtt.c index 8482477b97..87b94c0f75 100644 --- a/lib/mqtt.c +++ b/lib/mqtt.c @@ -347,8 +347,10 @@ static CURLcode mqtt_connect(struct Curl_easy *data) result = mqtt_send(data, packet, packetlen); end: - if(packet) + if(packet) { + curlx_memzero(packet, packetlen); curlx_free(packet); + } Curl_creds_unlink(&data->state.creds); return result; } diff --git a/lib/setopt.c b/lib/setopt.c index e2e30622f1..6e366456c0 100644 --- a/lib/setopt.c +++ b/lib/setopt.c @@ -154,6 +154,7 @@ static CURLcode setstropt_userpwd(const char *option, char **userp, curlx_free(*userp); *userp = user; + curlx_strzero(*passwdp); curlx_free(*passwdp); *passwdp = passwd; @@ -1657,6 +1658,7 @@ static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option, result = Curl_urldecode(p, 0, &s->str[STRING_PROXYPASSWORD], NULL, REJECT_ZERO); curlx_free(u); + curlx_strzero(p); curlx_free(p); break; } diff --git a/lib/url.c b/lib/url.c index 8da2aca924..3b0663515b 100644 --- a/lib/url.c +++ b/lib/url.c @@ -153,6 +153,15 @@ void Curl_freeset(struct Curl_easy *data) enum dupblob j; for(i = (enum dupstring)0; i < STRING_LAST; i++) { + if(i == STRING_PASSWORD || + i == STRING_KEY_PASSWD || +#ifndef CURL_DISABLE_PROXY + i == STRING_PROXYPASSWORD || + i == STRING_KEY_PASSWD_PROXY || +#endif + i == STRING_BEARER) { + curlx_strzero(data->set.str[i]); + } curlx_safefree(data->set.str[i]); } diff --git a/lib/urlapi.c b/lib/urlapi.c index 7a926debb6..1739b21bcc 100644 --- a/lib/urlapi.c +++ b/lib/urlapi.c @@ -69,6 +69,7 @@ static void free_urlhandle(struct Curl_URL *u) { curlx_free(u->scheme); curlx_free(u->user); + curlx_strzero(u->password); curlx_free(u->password); curlx_free(u->options); curlx_free(u->host); @@ -322,6 +323,7 @@ UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u, } if(passwdp) { + curlx_strzero(u->password); curlx_free(u->password); u->password = passwdp; } @@ -338,6 +340,7 @@ UNITTEST CURLUcode parse_hostname_login(struct Curl_URL *u, out: curlx_free(userp); + curlx_strzero(passwdp); curlx_free(passwdp); curlx_free(optionsp); curlx_safefree(u->user); @@ -1783,6 +1786,7 @@ static CURLUcode urlset_clear(CURLU *u, CURLUPart what) curlx_safefree(u->user); break; case CURLUPART_PASSWORD: + curlx_strzero(u->password); curlx_safefree(u->password); break; case CURLUPART_OPTIONS: @@ -2029,6 +2033,8 @@ nomem: } } + if(what == CURLUPART_PASSWORD) + curlx_strzero(*storep); curlx_free(*storep); *storep = (char *)CURL_UNCONST(newp); } diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c index 3feb3e7824..ab9373b240 100644 --- a/src/tool_cfgable.c +++ b/src/tool_cfgable.c @@ -145,7 +145,9 @@ static void free_config_fields(struct OperationConfig *config) curlx_safefree(config->proxy_key); curlx_safefree(config->key_type); curlx_safefree(config->proxy_key_type); + curlx_strzero(config->key_passwd); curlx_safefree(config->key_passwd); + curlx_strzero(config->proxy_key_passwd); curlx_safefree(config->proxy_key_passwd); curlx_safefree(config->pubkey); curlx_safefree(config->hostpubmd5); @@ -158,6 +160,7 @@ static void free_config_fields(struct OperationConfig *config) curlx_safefree(config->request_target); curlx_safefree(config->customrequest); curlx_safefree(config->krblevel); + curlx_strzero(config->oauth_bearer); curlx_safefree(config->oauth_bearer); curlx_safefree(config->sasl_authzid); curlx_safefree(config->unix_socket_path);