Improve loading of validator tokens (RIPD-1687):

A deliberately malformed token can cause the server to crash during
startup. This is not remotely exploitable and would require someone
with access to the configuration file of the server to make changes
and then restart the server.

Acknowledgements:
Guido Vranken for responsibly disclosing this issue.

Bug Bounties and Responsible Disclosures:
We welcome reviews of the rippled code and urge researchers to
responsibly disclose any issues they may find.

Ripple is generously sponsoring a bug bounty program for the
rippled project. For more information please visit:

    https://ripple.com/bug-bounty
This commit is contained in:
Nik Bougalis
2020-04-25 00:27:23 -07:00
parent 2827de4d63
commit 6c72d5cf7e
4 changed files with 23 additions and 38 deletions

View File

@@ -240,52 +240,44 @@ Manifest::getMasterSignature() const
return st.getFieldVL(sfMasterSignature);
}
ValidatorToken::ValidatorToken(std::string const& m, SecretKey const& valSecret)
: manifest(m), validationSecret(valSecret)
{
}
boost::optional<ValidatorToken>
ValidatorToken::make_ValidatorToken(std::vector<std::string> const& tokenBlob)
loadValidatorToken(std::vector<std::string> const& blob)
{
try
{
std::string tokenStr;
tokenStr.reserve(std::accumulate(
tokenBlob.cbegin(),
tokenBlob.cend(),
blob.cbegin(),
blob.cend(),
std::size_t(0),
[](std::size_t init, std::string const& s) {
return init + s.size();
}));
for (auto const& line : tokenBlob)
for (auto const& line : blob)
tokenStr += beast::rfc2616::trim(line);
tokenStr = base64_decode(tokenStr);
Json::Reader r;
Json::Value token;
if (!r.parse(tokenStr, token))
return boost::none;
if (token.isMember("manifest") && token["manifest"].isString() &&
token.isMember("validation_secret_key") &&
token["validation_secret_key"].isString())
if (r.parse(tokenStr, token))
{
auto const ret =
strUnHex(token["validation_secret_key"].asString());
if (!ret || ret->empty())
return boost::none;
auto const m = token.get("manifest", Json::Value{});
auto const k = token.get("validation_secret_key", Json::Value{});
return ValidatorToken(
token["manifest"].asString(),
SecretKey(Slice{ret->data(), ret->size()}));
}
else
{
return boost::none;
if (m.isString() && k.isString())
{
auto const key = strUnHex(k.asString());
if (key && key->size() == 32)
return ValidatorToken{m.asString(), makeSlice(*key)};
}
}
return boost::none;
}
catch (std::exception const&)
{