Fix ledger_entry crash on invalid credentials request (#5189)

This commit is contained in:
Bronek Kozicki
2026-02-20 02:21:26 +09:00
committed by tequ
parent 780500bc35
commit 14af5e67fc
2 changed files with 137 additions and 4 deletions

View File

@@ -28,6 +28,7 @@
#include <xrpl/basics/StringUtilities.h>
#include <xrpl/beast/unit_test.h>
#include <xrpl/hook/Enum.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/STXChainBridge.h>
@@ -1213,6 +1214,42 @@ public:
checkErrorValue(jrr[jss::result], "malformedRequest", "");
}
{
// Failed, authorized_credentials contains string data
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
arr.append("foobar");
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, authorized_credentials contains arrays
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
Json::Value payload = Json::arrayValue;
payload.append(42);
arr.append(std::move(payload));
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, authorized_credentials is empty array
Json::Value jvParams;
@@ -1269,6 +1306,27 @@ public:
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, issuer is not set
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
Json::Value jo;
jo[jss::credential_type] = strHex(std::string_view(credType));
arr.append(std::move(jo));
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, issuer isn't string
Json::Value jvParams;
@@ -1291,6 +1349,30 @@ public:
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, issuer is an array
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
Json::Value jo;
Json::Value payload = Json::arrayValue;
payload.append(42);
jo[jss::issuer] = std::move(payload);
jo[jss::credential_type] = strHex(std::string_view(credType));
arr.append(std::move(jo));
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, issuer isn't valid encoded account
Json::Value jvParams;
@@ -1313,12 +1395,32 @@ public:
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, credential_type is not set
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
Json::Value jo;
jo[jss::issuer] = issuer.human();
arr.append(std::move(jo));
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, credential_type isn't string
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
@@ -1332,7 +1434,32 @@ public:
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(jrr[jss::result], "malformedRequest", "");
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
// Failed, credential_type is an array
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
auto& arr(
jvParams[jss::deposit_preauth][jss::authorized_credentials]);
Json::Value jo;
jo[jss::issuer] = issuer.human();
Json::Value payload = Json::arrayValue;
payload.append(42);
jo[jss::credential_type] = std::move(payload);
arr.append(std::move(jo));
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
{
@@ -1340,7 +1467,6 @@ public:
Json::Value jvParams;
jvParams[jss::ledger_index] = jss::validated;
jvParams[jss::deposit_preauth][jss::owner] = bob.human();
jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
jvParams[jss::deposit_preauth][jss::authorized_credentials] =
Json::arrayValue;
@@ -1354,7 +1480,8 @@ public:
auto const jrr =
env.rpc("json", "ledger_entry", to_string(jvParams));
checkErrorValue(jrr[jss::result], "malformedRequest", "");
checkErrorValue(
jrr[jss::result], "malformedAuthorizedCredentials", "");
}
}

View File

@@ -42,6 +42,12 @@ parseAuthorizeCredentials(Json::Value const& jv)
STArray arr(sfAuthorizeCredentials, jv.size());
for (auto const& jo : jv)
{
if (!jo.isObject() || //
!jo.isMember(jss::issuer) || !jo[jss::issuer].isString() ||
!jo.isMember(jss::credential_type) ||
!jo[jss::credential_type].isString())
return {};
auto const issuer = parseBase58<AccountID>(jo[jss::issuer].asString());
if (!issuer || !*issuer)
return {};