fix: Validate account_lines peer field type (#7728)

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Braedon Klock
2026-08-10 21:30:06 +00:00
committed by GitHub
parent 9c292fbe4f
commit 4173f7e499
3 changed files with 53 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)
- `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

@@ -94,6 +94,24 @@ public:
LedgerHeader const ledger3Info = env.closed()->header();
BEAST_EXPECT(ledger3Info.seq == 3);
{
// test peer non-string
auto testInvalidPeerParam = [&](auto const& param) {
json::Value params;
params[jss::account] = alice.human();
params[jss::peer] = param;
auto jrr = env.rpc("json", "account_lines", to_string(params))[jss::result];
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
BEAST_EXPECT(jrr[jss::error_message] == "Invalid field 'peer'.");
};
testInvalidPeerParam(1);
testInvalidPeerParam(1.1);
testInvalidPeerParam(true);
testInvalidPeerParam(json::Value(json::ValueType::Null));
testInvalidPeerParam(json::Value(json::ValueType::Object));
testInvalidPeerParam(json::Value(json::ValueType::Array));
}
{
// alice is funded but has no lines. An empty array is returned.
json::Value params;
@@ -775,6 +793,35 @@ public:
LedgerHeader const ledger3Info = env.closed()->header();
BEAST_EXPECT(ledger3Info.seq == 3);
{
// test peer non-string
auto testInvalidPeerParam = [&](auto const& param) {
json::Value params;
params[jss::account] = alice.human();
params[jss::peer] = param;
json::Value request;
request[jss::method] = "account_lines";
request[jss::jsonrpc] = "2.0";
request[jss::ripplerpc] = "2.0";
request[jss::id] = 5;
request[jss::params] = params;
auto const lines = env.rpc("json2", to_string(request));
BEAST_EXPECT(lines[jss::error][jss::error] == "invalidParams");
BEAST_EXPECT(lines[jss::error][jss::message] == "Invalid field 'peer'.");
BEAST_EXPECT(lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
BEAST_EXPECT(lines.isMember(jss::ripplerpc) && lines[jss::ripplerpc] == "2.0");
BEAST_EXPECT(lines.isMember(jss::id) && lines[jss::id] == 5);
};
testInvalidPeerParam(1);
testInvalidPeerParam(1.1);
testInvalidPeerParam(true);
testInvalidPeerParam(json::Value(json::ValueType::Null));
testInvalidPeerParam(json::Value(json::ValueType::Object));
testInvalidPeerParam(json::Value(json::ValueType::Array));
}
{
// alice is funded but has no lines. An empty array is returned.
json::Value params;

View File

@@ -107,7 +107,12 @@ doAccountLines(rpc::JsonContext& context)
std::string strPeer;
if (params.isMember(jss::peer))
{
if (!params[jss::peer].isString())
return rpc::invalidFieldError(jss::peer);
strPeer = params[jss::peer].asString();
}
auto const raPeerAccount = [&]() -> std::optional<AccountID> {
return strPeer.empty() ? std::nullopt : parseBase58<AccountID>(strPeer);