Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add blockRangeLimit and batchRequestLimit JSON-RPC flags to help prevent node DDoS #638

Merged

Conversation

dankostiuk
Copy link
Contributor

Description

This PR introduces 2 new server flags that help prevent node DDoS:
--json-rpc-block-range-limit and --json-rpc-batch-request-limit

Block Range Limit

During testing, we observed that a couple JSON-RPC requests that include block ranges could allow an attacker to use up all the resource on a particular node if they specify large ranges, essentially DDoS-ing that node. For example, the following request could take down any polygon-edge node running on a chain that consists of many blocks:

{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"0","toBlock":"latest"}]}

To prevent such an attack, this PR enforces a default block range limit of 1000, optionally giving the node operator the ability to override this by specifying a value for --json-rpc-block-range-limit on their node's server command.

Batch Request Limit

In addition to the above, since we currently don't have a limit for the allowed size of a batch JSON-RPC request body, attackers could spam RPC nodes with requests that contain thousands of batched requests, for example:

[
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 0}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 1}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 2}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 3}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 4}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 5}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 6}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 7}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 8}, 
	{"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 9},
        ...
        {"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": ["latest", true], "id": 99999},
]

Part of this PR also enforces a default batch request size of 20, optionally giving the node operator the ability to override this by specifying a value for --json-rpc-batch-request-limit on their node's server command.

Changes include

  • Bugfix (non-breaking change that solves an issue)
  • Hotfix (change that solves an urgent issue, and requires immediate attention)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (change that is not backwards-compatible and/or changes current functionality)

Checklist

  • I have assigned this PR to myself
  • I have added at least 1 reviewer
  • I have added the relevant labels
  • I have updated the official documentation
  • I have added sufficient documentation in code

Testing

  • I have tested this code with the official test suite
  • I have tested this code manually

Manual tests

  1. Run this branch on a node
  2. Attempt to query with {"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"0","toBlock":"1002"}]} (this exceeds the default value of 1000). Observe error message in response.
  3. Attempt to query with batch JSON-RPC request containing 25 entries (this exceeds the default of 20). Observe error message in response.
  4. Add --json-rpc-block-range-limit 1100 and --json-rpc-batch-request-limit 30 to the server command on the same node and restart the node.
  5. Attempt both queries from step 2. and 3. and observe that the node now responds with success responses.

Documentation update

Will create a separate documentation PR once this PR is approved.

@codecov
Copy link

codecov bot commented Jul 12, 2022

Codecov Report

Merging #638 (3993c58) into develop (f786241) will increase coverage by 0.02%.
The diff coverage is 100.00%.

❗ Current head 3993c58 differs from pull request most recent head ebedc51. Consider uploading reports for the commit ebedc51 to get more accurate results

@@             Coverage Diff             @@
##           develop     #638      +/-   ##
===========================================
+ Coverage    51.19%   51.22%   +0.02%     
===========================================
  Files          109      109              
  Lines        15807    15816       +9     
===========================================
+ Hits          8092     8101       +9     
  Misses        7032     7032              
  Partials       683      683              
Impacted Files Coverage Δ
jsonrpc/dispatcher.go 53.66% <100.00%> (+0.62%) ⬆️
jsonrpc/filter_manager.go 75.51% <100.00%> (+0.20%) ⬆️
jsonrpc/jsonrpc.go 18.23% <100.00%> (+0.48%) ⬆️
syncer/client.go 61.79% <0.00%> (-1.42%) ⬇️
network/server_discovery.go 75.79% <0.00%> (+1.91%) ⬆️

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

Copy link
Contributor

@Kourin1996 Kourin1996 left a comment

Choose a reason for hiding this comment

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

Hello, Thank you for PR! The code looks good and it works completely. I've left some minor issues. It'd be cool if you could fix them

command/server/server.go Outdated Show resolved Hide resolved
command/server/server.go Outdated Show resolved Hide resolved
jsonrpc/dispatcher.go Outdated Show resolved Hide resolved
jsonrpc/dispatcher_test.go Outdated Show resolved Hide resolved
jsonrpc/dispatcher_test.go Outdated Show resolved Hide resolved
jsonrpc/dispatcher_test.go Outdated Show resolved Hide resolved
jsonrpc/dispatcher_test.go Outdated Show resolved Hide resolved
@zivkovicmilos zivkovicmilos added this to the 0.5 milestone Jul 25, 2022
Copy link
Contributor

@zivkovicmilos zivkovicmilos left a comment

Choose a reason for hiding this comment

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

Looks great 💯

Thank you for the contribution, as always 🙏

Please make sure to pull in the latest develop changes, and to check out the comment I've left.
We're good to go with this PR as soon as that's resolved 🚀

@zivkovicmilos zivkovicmilos added the feature New update to Polygon Edge label Jul 27, 2022
Conflicts:
	jsonrpc/filter_manager.go
	jsonrpc/filter_manager_test.go
@zivkovicmilos zivkovicmilos merged commit 8502125 into 0xPolygon:develop Jul 28, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Jul 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature New update to Polygon Edge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants