fix: Validate account/ident type in gateway_balances (#7655)

This commit is contained in:
luisfernandomendozav
2026-08-11 13:23:07 +00:00
committed by GitHub
parent c74724a719
commit d43e5acaa7
3 changed files with 47 additions and 0 deletions

View File

@@ -54,6 +54,7 @@ This section contains changes targeting a future version.
- `submit`: The `fail_hard` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `subscribe`: The `taker` field in the `books` array now returns `actMalformed` instead of `badIssuer` if the value is not a valid account. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- Fixed a bug in `Forwarded` HTTP header parsing where the extracted IP address could be incorrect when no comma or semicolon delimiter follows the address. This could cause the server to misidentify a client's IP address when operating behind a reverse proxy. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `gateway_balances`: The `account` and `ident` fields now return an `invalidParams` error if the value is not a string, instead of an `internal` error. [#7655](https://github.com/XRPLF/rippled/pull/7655)
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
## XRP Ledger server version 3.1.0

View File

@@ -176,6 +176,45 @@ public:
});
}
void
testGWBInvalidAccount(FeatureBitset features)
{
testcase("Gateway Balances with non-string account/ident");
using namespace std::chrono_literals;
using namespace jtx;
Env env(*this, features);
Account const alice{"alice"};
env.fund(XRP(10000), alice);
env.close();
auto wsc = makeWSClient(env.app().config());
// A non-string "account" must be rejected cleanly with invalidParams
// rather than throwing a Json::LogicError that surfaces as internal.
json::Value qry;
qry[jss::account] = 42;
qry[jss::hotwallet] = alice.human();
forAllApiVersions([&, this](unsigned apiVersion) {
qry[jss::api_version] = apiVersion;
auto jv = wsc->invoke("gateway_balances", qry);
expect(jv[jss::status] == "error");
BEAST_EXPECT(jv[jss::result][jss::error] == "invalidParams");
});
// The same applies to a non-string "ident".
json::Value qry2;
qry2[jss::ident] = 42;
forAllApiVersions([&, this](unsigned apiVersion) {
qry2[jss::api_version] = apiVersion;
auto jv = wsc->invoke("gateway_balances", qry2);
expect(jv[jss::status] == "error");
BEAST_EXPECT(jv[jss::result][jss::error] == "invalidParams");
});
}
void
testGWBOverflow()
{
@@ -280,6 +319,7 @@ public:
{
testGWB(feature);
testGWBApiVersions(feature);
testGWBInvalidAccount(feature);
}
testGWBWithMPT();
testGWBOverflow();

View File

@@ -63,6 +63,12 @@ doGatewayBalances(rpc::JsonContext& context)
if (!(params.isMember(jss::account) || params.isMember(jss::ident)))
return rpc::missingFieldError(jss::account);
if (params.isMember(jss::account) && !params[jss::account].isString())
return rpc::invalidFieldError(jss::account);
if (params.isMember(jss::ident) && !params[jss::ident].isString())
return rpc::invalidFieldError(jss::ident);
std::string const strIdent(
params.isMember(jss::account) ? params[jss::account].asString()
: params[jss::ident].asString());