Skip to content

Bound the account count accepted by wallet RPC commands - #5121

Open
pwojcikdev wants to merge 3 commits into
nanocurrency:developfrom
pwojcikdev:rpc-account-count-limit
Open

Bound the account count accepted by wallet RPC commands#5121
pwojcikdev wants to merge 3 commits into
nanocurrency:developfrom
pwojcikdev:rpc-account-count-limit

Conversation

@pwojcikdev

@pwojcikdev pwojcikdev commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

accounts_create and wallet_change_seed both loop over a caller-supplied count creating accounts, with no upper bound. A large count leaves the wallet unusable for the duration of the request, and the parameter accepts anything that parses into 64 bits.

wallet_change_seed had a second problem: it truncated its uint64 count into a uint32, so count=4294967296 became 0 — which selects auto-detect, a different operation than the caller asked for. Any multiple of 2^32 behaved the same way.

Both handlers now reject counts above max_accounts_per_request (100000) with invalid_count, following the range check account_create already applies to its index parameter.

wallet_change_seed additionally validates before touching the wallet. count_optional_impl sets ec on a malformed count, but the handler ignored it and replaced the seed anyway, surfacing the error only after the change had been made. A rejected request now leaves the existing seed in place.

Tests:

  • accounts_create_count_limit asserts the request is rejected and no account is created.
  • wallet_change_seed_count_rejected drives 100001, 4294967295, 4294967296 and 12abc, asserting each is rejected and that the existing seed survives. The last two are the interesting ones: 4294967296 previously truncated into a ledger scan, and 12abc parses as 12 before failing on the trailing garbage, so it previously replaced the seed and created 12 accounts while returning "Invalid count" to the caller.

Verified against develop with the malformed count in isolation — the seed is replaced despite the error response:

nano/rpc_test/rpc.cpp:2738: Failure
Expected equality of these values:
  seed_before.value ()
    Which is: B85BEB2CD72CA115AAE131720BC2B0CB4C67F2CE2FCA835A2FE5432C2F8D6D90
  seed_after.value ()
    Which is: 62020C2CAE2B571F95199A8396D9E4B045F9E901A3C6A4870459BF297C8E642F

Related to #5119, which guards the same overflow one layer down in wallet::change_seed.

🤖 Generated with Claude Code

Reject counts above a shared limit in accounts_create and wallet_change_seed, and validate wallet_change_seed's count before replacing the seed.
@pwojcikdev pwojcikdev added documentation This item indicates the need for or supplies updated or expanded documentation rpc Changes related to Remote Procedure Calls labels Jul 29, 2026
@gr0vity-dev-bot

gr0vity-dev-bot commented Jul 29, 2026

Copy link
Copy Markdown

Test Results for Commit 4b97a2d

Pull Request 5121: Results
Overall Status:

Test Case Results

  • 5n4pr_conf_10k_bintree: PASS (Duration: 121s)
  • 5n4pr_conf_10k_change: PASS (Duration: 153s)
  • 5n4pr_conf_change_dependant: PASS (Duration: 118s)
  • 5n4pr_conf_change_independant: PASS (Duration: 116s)
  • 5n4pr_conf_send_dependant: PASS (Duration: 110s)
  • 5n4pr_conf_send_independant: PASS (Duration: 111s)
  • 5n4pr_rocks_10k_bintree: PASS (Duration: 112s)
  • 5n4pr_rocks_10k_change: PASS (Duration: 156s)

Last updated: 2026-07-29 23:16:21 UTC

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens wallet-related RPC endpoints against abusive/overflowing count parameters by enforcing a per-request maximum and ensuring validation happens before mutating wallet state.

Changes:

  • Add a shared per-request account limit (max_accounts_per_request = 100000) and reject requests exceeding it.
  • Fix wallet_change_seed to validate count (including parse errors) before changing the wallet seed.
  • Add RPC tests asserting over-limit requests are rejected and do not partially apply changes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
nano/node/json_handler.cpp Enforces count bounds for accounts_create and wallet_change_seed; ensures wallet_change_seed validates before mutating the wallet.
nano/rpc_test/rpc.cpp Adds regression tests for the new count limit and seed immutability on rejected requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nano/node/json_handler.cpp Outdated
Comment on lines +4755 to +4759
// Count is the highest index to restore, so the seed yields one more account than its value
auto count (rpc_l->count_optional_impl (0));
if (!rpc_l->ec && count > max_accounts_per_request)
{
nano::public_key account (wallet->change_seed (seed, count));
rpc_l->response_l.put ("success", "");
rpc_l->response_l.put ("last_restored_account", account.to_account ());
auto index (wallet->get_deterministic_index ());
debug_assert (index > 0);
rpc_l->response_l.put ("restored_count", std::to_string (index));
rpc_l->ec = nano::error_common::invalid_count;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation This item indicates the need for or supplies updated or expanded documentation rpc Changes related to Remote Procedure Calls

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants