From c6249d9b3f0c2f2bf44e220299a076a7ccbc39db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Tue, 11 Jun 2024 12:19:52 +0200 Subject: [PATCH] enh(Net): clear out stored credentials --- Net/include/Poco/Net/NameValueCollection.h | 9 ++++++ Net/src/HTTPBasicCredentials.cpp | 5 ++-- Net/src/HTTPDigestCredentials.cpp | 33 +++++++++++++++------- Net/src/HTTPNTLMCredentials.cpp | 6 ++-- Net/src/HTTPRequest.cpp | 6 ++-- Net/src/NameValueCollection.cpp | 24 ++++++++++++++++ 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Net/include/Poco/Net/NameValueCollection.h b/Net/include/Poco/Net/NameValueCollection.h index bd1993a5a..5f5ad2c37 100644 --- a/Net/include/Poco/Net/NameValueCollection.h +++ b/Net/include/Poco/Net/NameValueCollection.h @@ -109,9 +109,18 @@ public: void erase(const std::string& name); /// Removes all name-value pairs with the given name. + void secureErase(const std::string& name); + /// Securely erases all name-value pairs with the given name + /// by first overwriting the value with zeroes before + /// removing it. + void clear(); /// Removes all name-value pairs and their values. + void secureClear(); + /// Removes all name-value pairs and their values. + /// Additionally, all values are also overwritten with zeroes. + private: HeaderMap _map; }; diff --git a/Net/src/HTTPBasicCredentials.cpp b/Net/src/HTTPBasicCredentials.cpp index 5b5e89897..9307085e9 100644 --- a/Net/src/HTTPBasicCredentials.cpp +++ b/Net/src/HTTPBasicCredentials.cpp @@ -66,13 +66,14 @@ HTTPBasicCredentials::HTTPBasicCredentials(const std::string& authInfo) HTTPBasicCredentials::~HTTPBasicCredentials() { + clear(); } void HTTPBasicCredentials::clear() { - _username.clear(); - _password.clear(); + Poco::secureClear(_username); + Poco::secureClear(_password); } diff --git a/Net/src/HTTPDigestCredentials.cpp b/Net/src/HTTPDigestCredentials.cpp index 736538ade..a53feb84b 100644 --- a/Net/src/HTTPDigestCredentials.cpp +++ b/Net/src/HTTPDigestCredentials.cpp @@ -25,8 +25,8 @@ #include "Poco/Net/HTTPResponse.h" #include "Poco/NumberFormatter.h" #include "Poco/StringTokenizer.h" +#include "Poco/String.h" -#include namespace { @@ -108,13 +108,17 @@ const std::string HTTPDigestCredentials::NC_PARAM("nc"); int HTTPDigestCredentials::_nonceCounter(0); Poco::FastMutex HTTPDigestCredentials::_nonceMutex; -class HTTPDigestCredentials::DigestEngineProvider { + +class HTTPDigestCredentials::DigestEngineProvider +{ public: - DigestEngineProvider(std::string algorithm): _algorithm(algorithm) { + DigestEngineProvider(std::string algorithm): _algorithm(algorithm) + { _isSessionAlgorithm = _algorithm.find("sess") != std::string::npos; } - DigestEngine& engine() { + DigestEngine& engine() + { if (icompare(_algorithm, SHA_ALGORITHM) == 0 || icompare(_algorithm, SHA_SESS_ALGORITHM) == 0) { return _sha1Engine; @@ -122,21 +126,26 @@ public: if (icompare(_algorithm, SHA_256_ALGORITHM) == 0 || icompare(_algorithm, SHA_256_SESS_ALGORITHM) == 0) { return _sha256Engine; - } else if (icompare(_algorithm, SHA_512_256_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_256_SESS_ALGORITHM) == 0) + } + else if (icompare(_algorithm, SHA_512_256_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_256_SESS_ALGORITHM) == 0) { return _sha512_256Engine; - } else if (icompare(_algorithm, SHA_512_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_SESS_ALGORITHM) == 0) + } + else if (icompare(_algorithm, SHA_512_ALGORITHM) == 0 || icompare(_algorithm, SHA_512_SESS_ALGORITHM) == 0) { return _sha512; } - else { + else + { return _md5Engine; } } - bool isSessionAlgorithm() { + bool isSessionAlgorithm() + { return _isSessionAlgorithm; } + private: std::string _algorithm; SHA1Engine _sha1Engine; @@ -147,6 +156,7 @@ private: bool _isSessionAlgorithm; }; + HTTPDigestCredentials::HTTPDigestCredentials() { } @@ -161,6 +171,7 @@ HTTPDigestCredentials::HTTPDigestCredentials(const std::string& username, const HTTPDigestCredentials::~HTTPDigestCredentials() { + clear(); } @@ -185,8 +196,8 @@ void HTTPDigestCredentials::setPassword(const std::string& password) void HTTPDigestCredentials::clear() { - _username.clear(); - _password.clear(); + Poco::secureClear(_username); + Poco::secureClear(_password); } @@ -404,6 +415,7 @@ int HTTPDigestCredentials::updateNonceCounter(const std::string& nonce) return iter->second; } + bool HTTPDigestCredentials::isAlgorithmSupported(const std::string& algorithm) const { bool isAlgorithmSupported = std::find_if(std::begin(SUPPORTED_ALGORITHMS), @@ -416,4 +428,5 @@ bool HTTPDigestCredentials::isAlgorithmSupported(const std::string& algorithm) c return isAlgorithmSupported; } + } } // namespace Poco::Net diff --git a/Net/src/HTTPNTLMCredentials.cpp b/Net/src/HTTPNTLMCredentials.cpp index ddc9575c4..5ae497e5b 100644 --- a/Net/src/HTTPNTLMCredentials.cpp +++ b/Net/src/HTTPNTLMCredentials.cpp @@ -21,6 +21,7 @@ #include "Poco/DateTime.h" #include "Poco/NumberFormatter.h" #include "Poco/Exception.h" +#include "Poco/String.h" namespace Poco { @@ -44,6 +45,7 @@ HTTPNTLMCredentials::HTTPNTLMCredentials(const std::string& username, const std: HTTPNTLMCredentials::~HTTPNTLMCredentials() { + clear(); } @@ -54,8 +56,8 @@ void HTTPNTLMCredentials::reset() void HTTPNTLMCredentials::clear() { - _username.clear(); - _password.clear(); + Poco::secureClear(_username); + Poco::secureClear(_password); _host.clear(); } diff --git a/Net/src/HTTPRequest.cpp b/Net/src/HTTPRequest.cpp index 2759c1f55..d6dd88397 100644 --- a/Net/src/HTTPRequest.cpp +++ b/Net/src/HTTPRequest.cpp @@ -84,6 +84,8 @@ HTTPRequest::HTTPRequest(const HTTPRequest& other): HTTPRequest::~HTTPRequest() { + secureErase(AUTHORIZATION); + secureErase(PROXY_AUTHORIZATION); } @@ -194,7 +196,7 @@ void HTTPRequest::setCredentials(const std::string& scheme, const std::string& a void HTTPRequest::removeCredentials() { - erase(AUTHORIZATION); + secureErase(AUTHORIZATION); } @@ -218,7 +220,7 @@ void HTTPRequest::setProxyCredentials(const std::string& scheme, const std::stri void HTTPRequest::removeProxyCredentials() { - erase(PROXY_AUTHORIZATION); + secureErase(PROXY_AUTHORIZATION); } diff --git a/Net/src/NameValueCollection.cpp b/Net/src/NameValueCollection.cpp index f30985880..10e657f97 100644 --- a/Net/src/NameValueCollection.cpp +++ b/Net/src/NameValueCollection.cpp @@ -157,10 +157,34 @@ void NameValueCollection::erase(const std::string& name) } +void NameValueCollection::secureErase(const std::string& name) +{ + Iterator it = _map.find(name); + while (it != _map.end()) + { + Poco::secureClear(it->second); + _map.erase(it); + it = _map.find(name); + } +} + + void NameValueCollection::clear() { _map.clear(); } +void NameValueCollection::secureClear() +{ + Iterator it = _map.begin(); + while (it != _map.end()) + { + Poco::secureClear(it->second); + ++it; + } + _map.clear(); +} + + } } // namespace Poco::Net