Skip to content

rpc: add limit for batch request items and response size #268

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

Open
wants to merge 2 commits into
base: release/v0.20.x-cronos
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features

* (rpc) [#1682](https://github.com/evmos/ethermint/pull/1682) Add config for maximum number of bytes returned from eth_call.
* (rpc) [#268](https://github.com/crypto-org-chain/ethermint/pull/268) Add config for maximum number of requests and bytes returned from a batched call.

### Bug Fixes

Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/btcsuite/btcd/btcutil v1.1.3
github.com/cosmos/cosmos-sdk v0.46.13-0.20230524145004-5b02d46853ba
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/gogoproto v1.4.10
github.com/cosmos/ibc-go/v5 v5.0.0-rc0
github.com/davecgh/go-spew v1.1.1
github.com/ethereum/go-ethereum v1.10.19
Expand Down Expand Up @@ -37,7 +38,7 @@ require (
golang.org/x/net v0.9.0
golang.org/x/text v0.9.0
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4
google.golang.org/grpc v1.54.0
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0
sigs.k8s.io/yaml v1.3.0
)
Expand Down Expand Up @@ -104,7 +105,7 @@ require (
github.com/go-stack/stack v1.8.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/gateway v1.1.0 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.2 // indirect
Expand Down Expand Up @@ -184,7 +185,7 @@ require (
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/oauth2 v0.6.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/term v0.7.0 // indirect
Expand All @@ -202,6 +203,7 @@ replace (
// use cosmos keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.46.13-0.20230524145004-5b02d46853ba
github.com/ethereum/go-ethereum => github.com/mmsqe/go-ethereum v1.10.19-0.20230614011134-2cfbc432f7a5
Copy link
Author

Choose a reason for hiding this comment

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

// Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities.
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.0
Expand Down
39 changes: 23 additions & 16 deletions go.sum

Large diffs are not rendered by default.

20 changes: 12 additions & 8 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ schema = 3
[mod."github.com/cosmos/go-bip39"]
version = "v1.0.0"
hash = "sha256-Qm2aC2vaS8tjtMUbHmlBSagOSqbduEEDwc51qvQaBmA="
[mod."github.com/cosmos/gogoproto"]
version = "v1.4.10"
hash = "sha256-Anm4O3bUONsN7J9Psg9E+oQasmUyoGc7UE1aaHJaehE="
[mod."github.com/cosmos/iavl"]
version = "v0.19.5"
hash = "sha256-8PerCyxQrBCtr2zkhgriqauhCSoIe580dsYpZ44o+cE="
Expand Down Expand Up @@ -175,8 +178,9 @@ schema = 3
version = "v1.0.0"
hash = "sha256-k1DYvCqO3BKNcGEve/nMW0RxzMkK2tGfXbUbycqcVSo="
[mod."github.com/ethereum/go-ethereum"]
version = "v1.10.19"
hash = "sha256-7FPnTGcCb8Xd1QVR+6PmGTaHdTY1mm/8osFTW1JLuG8="
version = "v1.10.19-0.20230614011134-2cfbc432f7a5"
hash = "sha256-2t0vpaDAGgm8T3QK7L6SClZg6hlpnk+ZxX6LMzEgqpE="
replaced = "github.com/mmsqe/go-ethereum"
[mod."github.com/felixge/httpsnoop"]
version = "v1.0.1"
hash = "sha256-TNXnnC/ZGNY9lInAcES1cBGqIdEljKuh5LH/khVFjVk="
Expand Down Expand Up @@ -218,8 +222,8 @@ schema = 3
hash = "sha256-TKa//aFXpWH+yK/cN1oaaqhipZpPUovekP6oA9vLIHY="
replaced = "github.com/regen-network/protobuf"
[mod."github.com/golang/glog"]
version = "v1.0.0"
hash = "sha256-bglITqRgzi52zc6FoYYnfCvrjFWV4RVOacPCnbEBom4="
version = "v1.1.0"
hash = "sha256-FgkBzn32nsq5Fpz0KKOrOqKap6pa2A1P3N2C0/Qp820="
[mod."github.com/golang/groupcache"]
version = "v0.0.0-20210331224755-41bb18bfe9da"
hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0="
Expand Down Expand Up @@ -527,8 +531,8 @@ schema = 3
version = "v0.9.0"
hash = "sha256-EG5GRDq282twyce8uugsDTjMz1pNn6zPcyVTZmSiJ14="
[mod."golang.org/x/oauth2"]
version = "v0.5.0"
hash = "sha256-+ns+lPELOJdb1YpIxQRBVQeSEsn0VhnKPnHg5Q0NOH4="
version = "v0.6.0"
hash = "sha256-M6yqSRqMcgp4bOCa4ey8/13z/0BrjQgyUQXJZU1hmnw="
[mod."golang.org/x/sync"]
version = "v0.1.0"
hash = "sha256-Hygjq9euZ0qz6TvHYQwOZEjNiTbTh1nSLRAWZ6KFGR8="
Expand All @@ -554,8 +558,8 @@ schema = 3
version = "v0.0.0-20230306155012-7f2fa6fef1f4"
hash = "sha256-mFnDrRD0B/fL+om/wkU/6ODFMzjaoeyoWy0vsmzQh1I="
[mod."google.golang.org/grpc"]
version = "v1.54.0"
hash = "sha256-2HzpK4s9zAGUv/26wChxbfkX3t4WB1bLM96O5gkQmro="
version = "v1.55.0"
hash = "sha256-UT1/x6XSkv1o2rJC2DI8CPvyB+nsFYUcZqtCPOdg42M="
[mod."google.golang.org/protobuf"]
version = "v1.30.0"
hash = "sha256-Y07NKhSuJQ2w7F7MAINQyBf+/hdMHOrxwA3B4ljQQKs="
Expand Down
14 changes: 14 additions & 0 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ const (

// DefaultReturnDataLimit is maximum number of bytes returned from eth_call or similar invocations
DefaultReturnDataLimit = 100000

// DefaultBatchRequestLimit is maximum number of requests in a batch
DefaultBatchRequestLimit = 1000

// DefaultBatchResponseMaxSize maximum number of bytes returned from a batched call
DefaultBatchResponseMaxSize = 25 * 1000 * 1000
)

var evmTracers = []string{"json", "markdown", "struct", "access_list"}
Expand Down Expand Up @@ -126,6 +132,10 @@ type JSONRPCConfig struct {
MetricsAddress string `mapstructure:"metrics-address"`
// ReturnDataLimit defines maximum number of bytes returned from `eth_call` or similar invocations
ReturnDataLimit int64 `mapstructure:"return-data-limit"`
// BatchRequestLimit maximum number of requests in a batch
BatchRequestLimit int64 `mapstructure:"batch-request-limit"`
// BatchResponseMaxSize maximum number of bytes returned from a batched call
BatchResponseMaxSize int64 `mapstructure:"batch-response-max-size"`
// FixRevertGasRefundHeight defines the upgrade height for fix of revert gas refund logic when transaction reverted
FixRevertGasRefundHeight int64 `mapstructure:"fix-revert-gas-refund-height"`
}
Expand Down Expand Up @@ -231,6 +241,8 @@ func DefaultJSONRPCConfig() *JSONRPCConfig {
EnableIndexer: false,
MetricsAddress: DefaultJSONRPCMetricsAddress,
ReturnDataLimit: DefaultReturnDataLimit,
BatchRequestLimit: DefaultBatchRequestLimit,
BatchResponseMaxSize: DefaultBatchResponseMaxSize,
FixRevertGasRefundHeight: DefaultFixRevertGasRefundHeight,
}
}
Expand Down Expand Up @@ -343,6 +355,8 @@ func GetConfig(v *viper.Viper) (Config, error) {
MetricsAddress: v.GetString("json-rpc.metrics-address"),
ReturnDataLimit: v.GetInt64("json-rpc.return-data-limit"),
FixRevertGasRefundHeight: v.GetInt64("json-rpc.fix-revert-gas-refund-height"),
BatchRequestLimit: v.GetInt64("json-rpc.batch-request-limit"),
BatchResponseMaxSize: v.GetInt64("json-rpc.batch-response-max-size"),
},
TLS: TLSConfig{
CertificatePath: v.GetString("tls.certificate-path"),
Expand Down
6 changes: 6 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ metrics-address = "{{ .JSONRPC.MetricsAddress }}"
# Maximum number of bytes returned from eth_call or similar invocations.
return-data-limit = {{ .JSONRPC.ReturnDataLimit }}

# Maximum number of requests in a batch.
batch-request-limit = {{ .JSONRPC.BatchRequestLimit }}

# Maximum number of bytes returned from a batched call.
batch-response-max-size = {{ .JSONRPC.BatchResponseMaxSize }}

# Upgrade height for fix of revert gas refund logic when transaction reverted.
fix-revert-gas-refund-height = {{ .JSONRPC.FixRevertGasRefundHeight }}

Expand Down
2 changes: 2 additions & 0 deletions server/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const (
// https://github.com/ethereum/go-ethereum/blob/master/metrics/metrics.go#L35-L55
JSONRPCEnableMetrics = "metrics"
JSONRPCReturnDataLimit = "json-rpc.return-data-limit"
JSONRPCBatchRequestLimit = "json-rpc.batch-request-limit"
JSONRPCBatchResponseMaxSize = "json-rpc.batch-response-max-size"
JSONRPCFixRevertGasRefundHeight = "json-rpc.fix-revert-gas-refund-height"
)

Expand Down
2 changes: 1 addition & 1 deletion server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func StartJSONRPC(ctx *server.Context,
}))

rpcServer := ethrpc.NewServer()

rpcServer.SetBatchLimits(int(config.JSONRPC.BatchRequestLimit), int(config.JSONRPC.BatchResponseMaxSize)) // add 0x: (3594240 + 2) * 4
allowUnprotectedTxs := config.JSONRPC.AllowUnprotectedTxs
rpcAPIArr := config.JSONRPC.API

Expand Down
2 changes: 2 additions & 0 deletions tests/integration_tests/configs/exploit.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ config {
'app-config'+: {
'json-rpc'+: {
'return-data-limit': 3594241, // memory_byte_size + 1
'batch-request-limit': 2,
'batch-response-max-size': 10,
},
},
},
Expand Down
25 changes: 25 additions & 0 deletions tests/integration_tests/test_exploit.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,28 @@ def expect_cb(result):
assert "error" not in item

run_test(custom_ethermint, concurrent, batch, expect_cb)


def test_batch_call(custom_ethermint):
concurrent = 1
batch = 3

def expect_cb(result):
for item in result:
assert "error" in item
assert "batch too large" in item["error"]["message"]
run_test(custom_ethermint, concurrent, batch, expect_cb)


def test_batch_large_call(custom_ethermint):
concurrent = 1
batch = 2

def expect_cb(result):
for i, item in enumerate(result):
if i == 0:
assert "error" not in item
else:
assert "error" in item
assert "response too large" in item["error"]["message"]
run_test(custom_ethermint, concurrent, batch, expect_cb)