mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-20 02:25:53 +00:00
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:
@@ -171,18 +171,11 @@ struct ValidatorToken
|
||||
{
|
||||
std::string manifest;
|
||||
SecretKey validationSecret;
|
||||
|
||||
private:
|
||||
ValidatorToken(std::string const& m, SecretKey const& valSecret);
|
||||
|
||||
public:
|
||||
ValidatorToken(ValidatorToken const&) = delete;
|
||||
ValidatorToken(ValidatorToken&& other) = default;
|
||||
|
||||
static boost::optional<ValidatorToken>
|
||||
make_ValidatorToken(std::vector<std::string> const& tokenBlob);
|
||||
};
|
||||
|
||||
boost::optional<ValidatorToken>
|
||||
loadValidatorToken(std::vector<std::string> const& blob);
|
||||
|
||||
enum class ManifestDisposition {
|
||||
/// Manifest is valid
|
||||
accepted = 0,
|
||||
|
||||
@@ -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&)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ ValidatorKeys::ValidatorKeys(Config const& config, beast::Journal j)
|
||||
|
||||
if (config.exists(SECTION_VALIDATOR_TOKEN))
|
||||
{
|
||||
if (auto const token = ValidatorToken::make_ValidatorToken(
|
||||
if (auto const token = loadValidatorToken(
|
||||
config.section(SECTION_VALIDATOR_TOKEN).lines()))
|
||||
{
|
||||
auto const pk =
|
||||
|
||||
@@ -534,14 +534,14 @@ public:
|
||||
"r7C0kw"
|
||||
"2AiTzSCjIzditQ8=";
|
||||
|
||||
auto const token = ValidatorToken::make_ValidatorToken(tokenBlob);
|
||||
auto const token = loadValidatorToken(tokenBlob);
|
||||
BEAST_EXPECT(token);
|
||||
BEAST_EXPECT(token->validationSecret == *valSecret);
|
||||
BEAST_EXPECT(token->manifest == manifest);
|
||||
}
|
||||
{
|
||||
std::vector<std::string> const badToken = {"bad token"};
|
||||
BEAST_EXPECT(!ValidatorToken::make_ValidatorToken(badToken));
|
||||
BEAST_EXPECT(!loadValidatorToken(badToken));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user