From b8577bd7b83b8f43470402cfbd059ee7134fa3ee Mon Sep 17 00:00:00 2001 From: Olek <115580134+oleks-rip@users.noreply.github.com> Date: Wed, 19 Nov 2025 11:58:18 -0500 Subject: [PATCH] Fix: Perform array size check (#6030) The `ledger_entry` and `deposit_preauth` requests require an array of credentials. However, the array size is not checked before is gets processing. This fix adds checks and return errors in case array size is too big. --- src/test/rpc/LedgerEntry_test.cpp | 4 +-- src/xrpld/rpc/handlers/LedgerEntry.cpp | 34 ++++++++++++++++++-------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/test/rpc/LedgerEntry_test.cpp b/src/test/rpc/LedgerEntry_test.cpp index a88f6ab612..61c2bd4e73 100644 --- a/src/test/rpc/LedgerEntry_test.cpp +++ b/src/test/rpc/LedgerEntry_test.cpp @@ -1122,7 +1122,7 @@ class LedgerEntry_test : public beast::unit_test::suite checkErrorValue( jrr[jss::result], "malformedAuthorizedCredentials", - "Invalid field 'authorized_credentials', not array."); + "Invalid field 'authorized_credentials', array empty."); } { @@ -1163,7 +1163,7 @@ class LedgerEntry_test : public beast::unit_test::suite checkErrorValue( jrr[jss::result], "malformedAuthorizedCredentials", - "Invalid field 'authorized_credentials', not array."); + "Invalid field 'authorized_credentials', array too long."); } } diff --git a/src/xrpld/rpc/handlers/LedgerEntry.cpp b/src/xrpld/rpc/handlers/LedgerEntry.cpp index b9dc97c49a..4c7ddbb141 100644 --- a/src/xrpld/rpc/handlers/LedgerEntry.cpp +++ b/src/xrpld/rpc/handlers/LedgerEntry.cpp @@ -35,8 +35,6 @@ #include #include -#include - namespace ripple { static Expected @@ -197,18 +195,41 @@ static Expected parseAuthorizeCredentials(Json::Value const& jv) { if (!jv.isArray()) + { return LedgerEntryHelpers::invalidFieldError( "malformedAuthorizedCredentials", jss::authorized_credentials, "array"); - STArray arr(sfAuthorizeCredentials, jv.size()); + } + + std::uint32_t const n = jv.size(); + if (n > maxCredentialsArraySize) + { + return Unexpected(LedgerEntryHelpers::malformedError( + "malformedAuthorizedCredentials", + "Invalid field '" + std::string(jss::authorized_credentials) + + "', array too long.")); + } + + if (n == 0) + { + return Unexpected(LedgerEntryHelpers::malformedError( + "malformedAuthorizedCredentials", + "Invalid field '" + std::string(jss::authorized_credentials) + + "', array empty.")); + } + + STArray arr(sfAuthorizeCredentials, n); for (auto const& jo : jv) { if (!jo.isObject()) + { return LedgerEntryHelpers::invalidFieldError( "malformedAuthorizedCredentials", jss::authorized_credentials, "array"); + } + if (auto const value = LedgerEntryHelpers::hasRequired( jo, {jss::issuer, jss::credential_type}, @@ -279,13 +300,6 @@ parseDepositPreauth(Json::Value const& dp, Json::StaticString const fieldName) auto const arr = parseAuthorizeCredentials(ac); if (!arr.has_value()) return Unexpected(arr.error()); - if (arr->empty() || (arr->size() > maxCredentialsArraySize)) - { - return LedgerEntryHelpers::invalidFieldError( - "malformedAuthorizedCredentials", - jss::authorized_credentials, - "array"); - } auto const& sorted = credentials::makeSorted(arr.value()); if (sorted.empty())