Skip to content

fix(jsonrpc,http): harden RPC/HTTP parameter validation#14

Open
0xbigapple wants to merge 7 commits into
release_v4.8.2from
fix/rpc-param-validation-guards
Open

fix(jsonrpc,http): harden RPC/HTTP parameter validation#14
0xbigapple wants to merge 7 commits into
release_v4.8.2from
fix/rpc-param-validation-guards

Conversation

@0xbigapple

@0xbigapple 0xbigapple commented Jun 9, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Adds length/format validation to several JSON-RPC and HTTP address-handling parameters, so
malformed or oversized input is rejected early instead of triggering O(n²) work or leaking
NullPointerException / -32001(json4j default error). Valid input is unaffected.

  1. Commons.decodeFromBase58Check — reject input whose length != 34 before the O(n²) Base58.decode; single funnel for every HTTP address input.
  2. JsonFormat.unescapeBytesSelfType — an invalid Base58 address (null / illegal char) now returns a clear invalid address error instead of a bare ByteString.copyFrom(null) NPE; covers all merge-path address fields.
  3. JsonRpcApiUtil.addressCompatibleToByteArray — cap length at ADDRESS_SIZE + 2 (the +2 keeps 0x-prefixed 21-byte addresses valid) before fromHexString.
  4. JsonRpcApiUtil.parseBlockNumber — tighten MAX_BLOCK_NUM_HEX_LEN 100 → 20, and route the (String, Wallet) overload through the single-arg parser so it also gets the length cap, overflow (longValueExact) and negative checks.
  5. TronJsonRpcImpl.getStorageAt — bound the storage key and parse it before the contract lookup; a >32-byte key now returns -32602 invalid storage key value instead of -32001 (json4j default error) .
  6. LogFilterWrapper — validate blockHash via the shared JsonRpcApiUtil.hashToByteArray (moved here from TronJsonRpcImpl).
  7. HASH_REGEX accepts only hex digits [0-9a-fA-F], so a non-hex hash is rejected as invalid hash value rather than slipping through to fromHexString.

Why are these changes required?

Several unauthenticated API entry points accepted unbounded / malformed input, causing two
classes of problem:

  • Algorithmic-complexity DoSdecodeFromBase58Check fed the whole string into the O(n²)
    Base58.decode; since the cost grows quadratically with length, a single oversized address
    payload (well within the 4 MB body cap) can tie up a request thread far out of proportion to
    its size — a cheap DoS the body cap and rate limiter don't stop. Block-number parsing likewise
    had no effective length bound before the O(n²) BigInteger constructor.
  • Leaked exceptions / unfriendly errors — an invalid address on the merge path returned a
    bare NullPointerException; eth_getStorageAt surfaced a RuntimeException as
    -32001 Data word can't exceed 32 bytes: xxx instead of -32602 invalid params;

This PR has been tested by:

  • Unit Tests
  • Manual Testing

Follow up

Extra details
Representative affected endpoints:

  • JSON-RPC — grouped by the guarded parameter:
    • block number (length 100 → 20):
    • storage index (bounded + parsed as a 32-byte word): eth_getStorageAt
    • block hash (now validated by the shared hashToByteArray)
    • address (length capped at ADDRESS_SIZE + 2)
  • HTTP /wallet/* — all covered by the Base58 length/DoS guard, but they differ on an invalid address:
    • most endpoints pre-convert via Util.getHexAddress and just return {} (e.g. getcontract,`visible=true) — unchanged;
    • endpoints that merge a Base58 field directly (e.g. getaccount, visible=true) get the NPE → invalid address fix;
    • endpoints that resolve the address via Util.getAddress(request) (e.g. getReward) get null for an invalid address and degrade to reward 0.

Summary by cubic

Hardened JSON-RPC and HTTP parameter validation to reject malformed, oversized, overflowing, or null inputs early. Prevents O(n²) work and maps failures to clear -32602 errors; valid input is unchanged.

  • Bug Fixes
    • Base58 address: enforce 34-char in Commons; HTTP merge path returns “invalid address” instead of NPE; logs downgraded to debug.
    • Hex address: cap length before decode in address helpers; uniform “invalid address” errors on invalid/oversized input.
    • Block number: set max length to 20; require 0x for hex path; both overloads share bounds/overflow checks; null inputs return “invalid block number”.
    • Storage key: validate length (max 66 incl. 0x) and parse before contract lookup; invalid keys return “invalid storage key value”.
    • Hash/topic: centralized hash parsing with anchored hex-only 32-byte regex; restored 63-char topic support with strict regex and padding; non-string filter elements in address/topics are rejected early.
    • Tx index: new length-capped parser (0x + 8 hex max) for transaction-by-index endpoints; malformed/oversized -> -32602; negative/out-of-range -> null result.
    • QUANTITY/fee limit: signed “0x-..” values are rejected; feeLimit uses StrictMathWrapper.multiplyExact; gas*fee overflow -> “invalid gas: fee limit overflow”.
    • ABI: buildCreateSmartContractTransaction catches deep-nesting StackOverflowError and returns “invalid abi”.

Written for commit e5a033a. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Stricter validation and safer handling for Base58 addresses, hashes, block numbers, storage keys, transaction indices, and ABI inputs; clearer, consistent error messages and fewer null/overflow failures.
  • Tests
    • Expanded tests covering oversized/invalid addresses, hashes, block numbers, storage keys, transaction indices, fee calculations, and deeply nested ABI rejection.

  Add length/format guards across the JSON-RPC and HTTP address-handling paths so
  malformed or oversized parameters are rejected early with a clear -32602 / error
  response, instead of triggering O(n^2) work or leaking NPE / Internal errors.

  - Commons.decodeFromBase58Check: reject non-34-char input before the O(n^2)
    Base58 decode; single funnel covering every HTTP address input.
  - JsonFormat.unescapeBytesSelfType: turn an invalid Base58 address (null or
    illegal-char) into a clear "invalid address" error instead of a bare
    ByteString.copyFrom(null) NPE; covers all merge-path address fields.
  - JsonRpcApiUtil.addressCompatibleToByteArray: cap length at ADDRESS_SIZE + 2
    (the +2 keeps 0x-prefixed 21-byte addresses valid) before fromHexString.
  - JsonRpcApiUtil.parseBlockNumber: tighten MAX_BLOCK_NUM_HEX_LEN 100 -> 20 and
    route the (String, Wallet) overload through the single-arg parser so it also
    gets the length cap, overflow (longValueExact) and negative checks.
  - TronJsonRpcImpl.getStorageAt: bound the storage key and parse it before the
    contract lookup; wrap DataWord parsing so a >32-byte key
    returns invalid-params instead of an Internal error.
  - Hoist hashToByteArray/HASH_REGEX into JsonRpcApiUtil so LogFilterWrapper's
    blockHash gets the same 32-byte-hash validation.
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Centralizes and tightens input validation: adds Base58 length checks, central hash validation, stricter block/quantity/index parsing, storage key guards, ABI parsing error handling, fee-limit safety, and updates HTTP/JSON-RPC call sites and tests to assert consistent error messages.

Changes

Input Validation Enhancement and Consolidation

Layer / File(s) Summary
Base58 Address Validation Contract
chainbase/src/main/java/org/tron/common/utils/Commons.java, framework/src/main/java/org/tron/core/services/http/JsonFormat.java, test files
Adds BASE58_ADDRESS_LENGTH and length guard in Commons; JsonFormat catches decode failures and throws InvalidEscapeSequence; HTTP tests for oversized and valid Base58Check addresses added.
JSON-RPC Validators and Limits
framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java
Adds regex import and TX_INDEX_ERROR; tightens addressCompatibleToByteArray; rejects negative parseQuantityValue; reduces MAX_BLOCK_NUM_HEX_LEN; enforces 0x prefix for hex block numbers.
TronJsonRpcImpl storage, ABI, fee, and tx index
framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java
Statically imports shared hash helpers; adds MAX_STORAGE_KEY_HEX_LEN; validates/parses storageIdx with try/catch and reuses parsed DataWord; uses parseTxIndex with bounds checks; wraps ABI merge StackOverflowError; switches to calcFeeLimit.
Log filter integration
framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilterWrapper.java, framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilter.java
Replaces ByteArray/topic conversions with JsonRpcApiUtil.hashToByteArray for blockHash and topic criteria handling.
Validation test coverage
framework/src/test/java/... (JsonrpcServiceTest, JsonRpcApiUtilTest, JsonRpcTest, GetAccountServletTest, GetRewardServletTest, BuildArgumentsTest)
Adds and tightens tests to assert exact error messages and edge-case behavior for oversized/invalid inputs, tx index parsing, deep ABI rejection, and fee overflow handling.

🎯 3 (Moderate) | ⏱️ ~25 minutes


A rabbit hops through code with care,
Checks each base58 byte and dare,
Hashes trimmed, indexes kept tight,
ABI safe from a nesting blight,
Errors clear — validation done right! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.04% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: hardening RPC/HTTP parameter validation across multiple endpoints to reject malformed inputs early.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/rpc-param-validation-guards

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@0xbigapple

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java`:
- Around line 424-442: The HASH_REGEX used by hashToByteArray allows non-hex
letters; update the regex constant HASH_REGEX to only permit valid hex digits
and anchor the pattern (e.g. change to "^(0x)?[0-9a-fA-F]{64}$") so
Pattern.matches rejects values with letters outside 0-9/a-f/A-F; keep throwing
JsonRpcInvalidParamsException from hashToByteArray when the pattern fails and
continue using ByteArray.fromHexString for conversion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f8e5b10-4e07-454f-a5b3-c0cfc3084593

📥 Commits

Reviewing files that changed from the base of the PR and between a41321c and 17f6208.

📒 Files selected for processing (9)
  • chainbase/src/main/java/org/tron/common/utils/Commons.java
  • framework/src/main/java/org/tron/core/services/http/JsonFormat.java
  • framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java
  • framework/src/main/java/org/tron/core/services/jsonrpc/TronJsonRpcImpl.java
  • framework/src/main/java/org/tron/core/services/jsonrpc/filters/LogFilterWrapper.java
  • framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java
  • framework/src/test/java/org/tron/core/services/http/GetAccountServletTest.java
  • framework/src/test/java/org/tron/core/services/http/GetRewardServletTest.java
  • framework/src/test/java/org/tron/core/services/jsonrpc/JsonRpcApiUtilTest.java

@0xbigapple 0xbigapple changed the title fix(jsonrpc): harden RPC/HTTP parameter validation fix(jsonrpc): harden RPC/HTTP parameter validation Jun 9, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1 issue found across 9 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java Outdated
@0xbigapple

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@0xbigapple 0xbigapple changed the title fix(jsonrpc): harden RPC/HTTP parameter validation fix(jsonrpc,http): harden RPC/HTTP parameter validation Jun 9, 2026
…and address

  Continue hardening the eth_* JSON-RPC parameter paths so malformed, oversized
  or overflowing inputs are rejected with a clear -32602 (or, for an out-of-range
  index, a null result) instead of leaking an Internal error, an uncaught
  Error/NPE, a DecoderException, or a silently wrong value.

  - eth_getTransactionByBlock{Hash,Number}AndIndex: parse the index via a new
    length-capped JsonRpcApiUtil.parseTxIndex (malformed / oversized / int-overflow
    index -> -32602); in the handler, a negative or out-of-range index
    (txIndex < 0 || >= tx count) returns a null result instead of letting
    block.getTransactions(-1) throw IndexOutOfBoundsException (-32603).
  - buildCreateSmartContractTransaction: a deeply nested ABI overflows the
    recursive JsonFormat parser; catch the StackOverflowError narrowly around the
    merge and map it to invalid-params ("invalid abi") instead of letting an
    Error escape.
  - buildCreate/buildTriggerSmartContractTransaction: compute feeLimit via
    JsonRpcApiUtil.calcFeeLimit (Math.multiplyExact) so an oversized gas no
    longer silently wraps gas*energyFee to a bogus (possibly negative) feeLimit.
  - parseQuantityValue: reject a signed ("0x-..") value/gas; QUANTITY is unsigned.
  - LogFilter topics: parse via the strict hashToByteArray (regex-validated 32-byte
    hash) instead of topicToByteArray, and remove the now-unused topicToByteArray.
  - addressToByteArray: cap length before fromHexString and wrap the decode so an
    oversized or invalid-hex address filter is invalid-params.
@github-actions

Copy link
Copy Markdown

❌ Math Usage Detection Results

Found forbidden usage of java.lang.Math in the following files:

./framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java

Please review if this usage is intended.

Caution

Note: You should use org.tron.common.math.StrictMathWrapper.
If you need to use java.lang.Math, please provide a justification.

@0xbigapple

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@0xbigapple

Copy link
Copy Markdown
Owner Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@0xbigapple I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 12 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcApiUtil.java Outdated
…er elements

 - Restore topicToByteArray for LogFilter topics, guard with (0x)?[0-9a-fA-F]{63,64}$ so the stripped zero is padded back by ByteArray.fromHexString, while non-hex or wrong-length input still gets a clean -32602.
 - LogFilter: validate element types before the (String) cast in the address array and nested topic array loops.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant