Skip to content

Sync geth: security fix#322

Open
SegueII wants to merge 11 commits intomainfrom
sync-gap-v1.16.3-v1.16.7-p0-p1
Open

Sync geth: security fix#322
SegueII wants to merge 11 commits intomainfrom
sync-gap-v1.16.3-v1.16.7-p0-p1

Conversation

@SegueII
Copy link
Copy Markdown
Contributor

@SegueII SegueII commented May 8, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added configurable log query limits for eth_getLogs filtering
    • Added WebSocket message size limit configuration
    • Added GraphQL query depth limit enforcement
  • Bug Fixes

    • Optimized contract code storage to skip empty deployments
    • Added duplicate transaction detection in protocol handlers
    • Improved peer cleanup handling during transaction fetching
    • Enhanced storage proof validation for oversized keys
  • Performance

    • Reduced unnecessary hook invocations during contract state changes

SegueII and others added 10 commits May 6, 2026 15:47
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@SegueII SegueII requested a review from a team as a code owner May 8, 2026 02:06
@SegueII SegueII requested review from panos-xyz and removed request for a team May 8, 2026 02:06
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack

Warning

Rate limit exceeded

@SegueII has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 49 minutes and 35 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9964587-5d04-4f86-990f-9b2b85791791

📥 Commits

Reviewing files that changed from the base of the PR and between a3515ba and 33add58.

📒 Files selected for processing (2)
  • graphql/graphql_test.go
  • rpc/server_test.go
📝 Walkthrough

Walkthrough

This PR introduces multiple independent improvements across go-ethereum: log query limits with CLI configuration, state hook optimization for unchanged code, conditional contract code storage in EVM, transaction protocol hardening via duplicate detection, GraphQL query depth limiting, configurable RPC WebSocket message size limits, and early validation in proof API.

Changes

Log Query Limit Feature

Layer / File(s) Summary
Configuration & Defaults
eth/ethconfig/config.go, eth/ethconfig/gen_config.go
ETH protocol config gains LogQueryLimit field (default 1000); TOML serialization updated.
CLI Flag Registration
cmd/geth/main.go, cmd/geth/usage.go, cmd/utils/flags.go
--rpc.logquerylimit CLI flag added to geth, wired into SetEthConfig and RegisterFilterAPI.
Log Query Validation
eth/filters/api.go
FilterAPI implements validateLogQuery helper enforcing maxTopics (4) and per-query width limits; errors added for exceeding both constraints.
Filter System Integration
eth/filters/filter_system.go
FilterSystem Config gains LogQueryLimit field; SubscribeLogs validates queries early before subscription setup.
Filter Tests
eth/filters/filter_system_test.go
TestPollingFilterErrCleanup, TestExceedLogQueryLimit, and TestLogQueryLimitZeroDisablesWidthLimit verify limit enforcement across GetLogs, NewFilter, and SubscribeLogs paths.

State & VM Optimizations

Layer / File(s) Summary
State Hook Optimization
core/state/statedb_hooked.go
SetCode computes code hash once and calls OnCodeChange hook only when hash changes, avoiding redundant invocations.
State Hook Tests
core/state/statedb_hooked_test.go
TestSetCodeNoChangeDoesNotHook validates that identical code assignments and repeated nil do not trigger additional hook calls.
EVM Contract Code Storage
core/vm/evm.go
Contract creation skips SetCode when initialization returns empty bytes, preventing empty contract deployment.
EVM Create Tests
core/vm/evm_create_test.go
TestCreateEmptyReturnSkipsSetCode and TestCreateNonEmptyReturnSetsCode validate SetCode invocation patterns during contract creation.

Transaction Protocol Hardening

Layer / File(s) Summary
Transaction Handler Duplicate Detection
eth/protocols/eth/handlers.go
handleTransactions and handlePooledTransactions66 build per-packet seen maps, detecting and rejecting duplicate transaction hashes with errDecode.
Transaction Handler Tests
eth/protocols/eth/handler_test.go
TestHandleTransactionsDuplicate and TestHandlePooledTransactions66Duplicate verify duplicate rejection; duplicateTxBackend/Decoder test helpers added.
Transaction Fetcher Cleanup
eth/fetcher/tx_fetcher.go
TxFetcher.loop removes dropped peers from alternates map per hash, cleaning empty entries.
Fetcher Cleanup Tests
eth/fetcher/tx_fetcher_test.go
TestTransactionFetcherDropAlternates verifies peer removal from alternates during drop events.

GraphQL & RPC Services

Layer / File(s) Summary
GraphQL Depth Limiting
graphql/service.go
maxQueryDepth constant (20) added; newHandler updated to apply graphql.MaxDepth during schema parsing; returns (*handler, error) instead of error.
GraphQL Tests
graphql/graphql_test.go
TestGraphQLMaxDepth verifies queries exceeding depth limit return MaxDepthExceeded error.
WebSocket Configuration
rpc/server.go, rpc/client_opt.go, rpc/websocket.go
Server gains wsReadLimit field and SetWebsocketReadLimit method; client gains WithWebsocketMessageSizeLimit option; newWebsocketCodec accepts explicit read limit parameter.
WebSocket Tests
rpc/server_test.go, rpc/websocket_test.go
TestServerWebsocketReadLimit and TestWebsocketLargeRead validate message size limits on server and client sides.

API Validation

Layer / File(s) Summary
GetProof Early Validation
internal/ethapi/api.go
GetProof pre-decodes all storageKeys before state access; decodeHash validates hex length (≤64 chars) upfront to reject invalid keys without backend interaction.
GetProof Tests
internal/ethapi/api_morph_test.go
TestDecodeHash and TestGetProofInvalidStorageKeyBeforeStateAccess verify hash decoding validation and early rejection before state access.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • morph-l2/go-ethereum#308: Modifies tracer behavior and hook wiring for OnCodeChange—related to this PR's state hook optimization changes.

Suggested reviewers

  • FletcherMan
  • Web3Jumb0

Poem

🐰 A rabbit hops through filters and hooks with glee,
Query limits set, WebSockets flow free,
Duplicate checks guard the tx stream so bright,
GraphQL depths measured, code storage just right,
Validation upfront—no backend surprise!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Sync geth: security fix' is vague and generic, using non-descriptive terms that don't convey meaningful information about the specific changes in this comprehensive changeset. Replace with a more specific title that describes the primary change, such as 'Add log query limits and WebSocket message size limits' or 'Implement RPC log filtering validation and transaction deduplication'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync-gap-v1.16.3-v1.16.7-p0-p1

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/ethapi/api.go (1)

992-1003: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

GetStorageAt still decodes the key after state access — same ordering this PR fixes in GetProof.

An invalid hexKey in eth_getStorageAt still triggers a full StateAndHeaderByNumberOrHash call before the decode error is returned. The fix is the same trivial reorder applied to GetProof.

🔧 Proposed fix
 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, hexKey string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) {
+	key, err := decodeHash(hexKey)
+	if err != nil {
+		return nil, fmt.Errorf("unable to decode storage key: %s", err)
+	}
 	state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
 	if state == nil || err != nil {
 		return nil, err
 	}
-	key, err := decodeHash(hexKey)
-	if err != nil {
-		return nil, fmt.Errorf("unable to decode storage key: %s", err)
-	}
 	res := state.GetState(address, key)
 	return res[:], state.Error()
 }
🤖 Prompt for 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.

In `@internal/ethapi/api.go` around lines 992 - 1003, GetStorageAt currently calls
s.b.StateAndHeaderByNumberOrHash before validating the hexKey, causing an
unnecessary state load on invalid input; move the decodeHash(hexKey) call (and
its error handling) to occur before calling s.b.StateAndHeaderByNumberOrHash,
then proceed to obtain state and header, check state/err, call
state.GetState(address, key) and return res and state.Error() as before.
🧹 Nitpick comments (2)
eth/filters/filter_system_test.go (1)

511-600: ⚡ Quick win

Add a regression test for negative LogQueryLimit config values.

Current tests cover >0 and 0, but not <0. A small case here would prevent reintroducing a misconfig path that can disable eth_getLogs behavior unexpectedly.

🤖 Prompt for 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.

In `@eth/filters/filter_system_test.go` around lines 511 - 600, Add a regression
test that sets Config{LogQueryLimit: -1} and verifies negative limits behave
like zero (i.e. disable width limiting): create a new test (e.g.,
TestLogQueryLimitNegativeDisablesWidthLimit) modeled on
TestLogQueryLimitZeroDisablesWidthLimit that constructs a wide FilterCriteria,
calls api.NewFilter and api.events.SubscribeLogs(ethereum.FilterQuery(...)) and
asserts no error, then checks that Topics length > maxTopics still returns
errExceedMaxTopics; reference Config.LogQueryLimit, NewFilter,
events.SubscribeLogs, errExceedMaxTopics and maxTopics when locating the logic
to test.
core/state/statedb_hooked.go (1)

172-181: ⚡ Quick win

newHash and prevHash use asymmetric empty-code handling — minor fragility.

prevHash falls back to the constant codehash.EmptyKeccakCodeHash when len(prev) == 0, but newHash always calls crypto.Keccak256Hash(code) — including when code is nil. This is correct only if codehash.EmptyKeccakCodeHash == crypto.Keccak256Hash(nil), which is currently true, but the asymmetry is fragile: if EmptyKeccakCodeHash is ever redefined (e.g., to a Poseidon-based sentinel), the comparison silently breaks and the hook fires for a no-op SetCode(addr, nil) call on an account with no code.

Apply the same guard symmetrically:

♻️ Proposed symmetric fix
-       newHash := crypto.Keccak256Hash(code)
-       if prevHash != newHash {
+       newHash := codehash.EmptyKeccakCodeHash
+       if len(code) != 0 {
+           newHash = crypto.Keccak256Hash(code)
+       }
+       if prevHash != newHash {
            s.hooks.OnCodeChange(address, prevHash, prev, newHash, code)
        }
🤖 Prompt for 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.

In `@core/state/statedb_hooked.go` around lines 172 - 181, The OnCodeChange hook
computes prevHash using codehash.EmptyKeccakCodeHash when prev is empty but
always computes newHash with crypto.Keccak256Hash(code), which is asymmetric and
fragile; update the block in the s.hooks.OnCodeChange path so newHash is
computed the same way as prevHash (i.e., if len(code) == 0 set newHash =
codehash.EmptyKeccakCodeHash else newHash = crypto.Keccak256Hash(code)) and then
compare prevHash vs newHash before calling s.hooks.OnCodeChange(address,
prevHash, prev, newHash, code); keep references to prev, code, prevHash, newHash
and s.hooks.OnCodeChange exactly as in the diff.
🤖 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 `@cmd/utils/flags.go`:
- Around line 1715-1717: The CLI/config parsing currently allows negative values
for RPCGlobalLogQueryLimit which are assigned into cfg.LogQueryLimit via
ctx.IsSet(RPCGlobalLogQueryLimit.Name) and ctx.Int(...); add validation there to
reject negatives: when ctx.IsSet(RPCGlobalLogQueryLimit.Name) read the int into
a temp, if temp < 0 return a validation error (or propagate an existing sanitize
error type) explaining rpc.logquerylimit must be non-negative instead of
assigning it to cfg.LogQueryLimit; ensure references to
RPCGlobalLogQueryLimit.Name, ctx.Int(...) and cfg.LogQueryLimit are used so the
correct branch is fixed.

In `@rpc/client_opt.go`:
- Around line 72-75: The WithWebsocketMessageSizeLimit API accepts negative
values which are silently ignored later; update WithWebsocketMessageSizeLimit to
validate messageSizeLimit at the API boundary by checking if messageSizeLimit <
0 and failing fast (panic with a clear message) so callers are warned
immediately, otherwise continue to set cfg.wsMessageSizeLimit =
&messageSizeLimit; reference the function name WithWebsocketMessageSizeLimit and
the cfg.wsMessageSizeLimit field when making this change.

In `@rpc/server.go`:
- Around line 85-87: SetWebsocketReadLimit currently accepts negative values;
add validation in the Server.SetWebsocketReadLimit method so that if limit is
negative it is guarded against (e.g., clamp to 0 or return early) instead of
assigning to s.wsReadLimit; update the method to check limit < 0 and handle by
setting s.wsReadLimit = 0 (or leaving existing value) to avoid silently
configuring an invalid read limit.

---

Outside diff comments:
In `@internal/ethapi/api.go`:
- Around line 992-1003: GetStorageAt currently calls
s.b.StateAndHeaderByNumberOrHash before validating the hexKey, causing an
unnecessary state load on invalid input; move the decodeHash(hexKey) call (and
its error handling) to occur before calling s.b.StateAndHeaderByNumberOrHash,
then proceed to obtain state and header, check state/err, call
state.GetState(address, key) and return res and state.Error() as before.

---

Nitpick comments:
In `@core/state/statedb_hooked.go`:
- Around line 172-181: The OnCodeChange hook computes prevHash using
codehash.EmptyKeccakCodeHash when prev is empty but always computes newHash with
crypto.Keccak256Hash(code), which is asymmetric and fragile; update the block in
the s.hooks.OnCodeChange path so newHash is computed the same way as prevHash
(i.e., if len(code) == 0 set newHash = codehash.EmptyKeccakCodeHash else newHash
= crypto.Keccak256Hash(code)) and then compare prevHash vs newHash before
calling s.hooks.OnCodeChange(address, prevHash, prev, newHash, code); keep
references to prev, code, prevHash, newHash and s.hooks.OnCodeChange exactly as
in the diff.

In `@eth/filters/filter_system_test.go`:
- Around line 511-600: Add a regression test that sets Config{LogQueryLimit: -1}
and verifies negative limits behave like zero (i.e. disable width limiting):
create a new test (e.g., TestLogQueryLimitNegativeDisablesWidthLimit) modeled on
TestLogQueryLimitZeroDisablesWidthLimit that constructs a wide FilterCriteria,
calls api.NewFilter and api.events.SubscribeLogs(ethereum.FilterQuery(...)) and
asserts no error, then checks that Topics length > maxTopics still returns
errExceedMaxTopics; reference Config.LogQueryLimit, NewFilter,
events.SubscribeLogs, errExceedMaxTopics and maxTopics when locating the logic
to test.
🪄 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: 126ab57d-a607-4b28-b972-b818dbdf59a9

📥 Commits

Reviewing files that changed from the base of the PR and between 39e9ab6 and a3515ba.

📒 Files selected for processing (25)
  • cmd/geth/main.go
  • cmd/geth/usage.go
  • cmd/utils/flags.go
  • core/state/statedb_hooked.go
  • core/state/statedb_hooked_test.go
  • core/vm/evm.go
  • core/vm/evm_create_test.go
  • eth/ethconfig/config.go
  • eth/ethconfig/gen_config.go
  • eth/fetcher/tx_fetcher.go
  • eth/fetcher/tx_fetcher_test.go
  • eth/filters/api.go
  • eth/filters/filter_system.go
  • eth/filters/filter_system_test.go
  • eth/protocols/eth/handler_test.go
  • eth/protocols/eth/handlers.go
  • graphql/graphql_test.go
  • graphql/service.go
  • internal/ethapi/api.go
  • internal/ethapi/api_morph_test.go
  • rpc/client_opt.go
  • rpc/server.go
  • rpc/server_test.go
  • rpc/websocket.go
  • rpc/websocket_test.go

Comment thread cmd/utils/flags.go
Comment on lines +1715 to +1717
if ctx.IsSet(RPCGlobalLogQueryLimit.Name) {
cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name)
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject negative rpc.logquerylimit values during config sanitization.

At Line 1715, negative values can flow from CLI/config into cfg.LogQueryLimit; later checks treat any negative as “everything exceeds limit”, effectively breaking all log queries.

Proposed fix
 	if ctx.IsSet(RPCGlobalLogQueryLimit.Name) {
 		cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name)
 	}
+	if cfg.LogQueryLimit < 0 {
+		Fatalf("--%s must be >= 0", RPCGlobalLogQueryLimit.Name)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ctx.IsSet(RPCGlobalLogQueryLimit.Name) {
cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name)
}
if ctx.IsSet(RPCGlobalLogQueryLimit.Name) {
cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name)
}
if cfg.LogQueryLimit < 0 {
Fatalf("--%s must be >= 0", RPCGlobalLogQueryLimit.Name)
}
🤖 Prompt for 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.

In `@cmd/utils/flags.go` around lines 1715 - 1717, The CLI/config parsing
currently allows negative values for RPCGlobalLogQueryLimit which are assigned
into cfg.LogQueryLimit via ctx.IsSet(RPCGlobalLogQueryLimit.Name) and
ctx.Int(...); add validation there to reject negatives: when
ctx.IsSet(RPCGlobalLogQueryLimit.Name) read the int into a temp, if temp < 0
return a validation error (or propagate an existing sanitize error type)
explaining rpc.logquerylimit must be non-negative instead of assigning it to
cfg.LogQueryLimit; ensure references to RPCGlobalLogQueryLimit.Name,
ctx.Int(...) and cfg.LogQueryLimit are used so the correct branch is fixed.

Comment thread rpc/client_opt.go
Comment on lines +72 to +75
func WithWebsocketMessageSizeLimit(messageSizeLimit int64) ClientOption {
return optionFunc(func(cfg *clientConfig) {
cfg.wsMessageSizeLimit = &messageSizeLimit
})
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate negative websocket size limits at the API boundary.

WithWebsocketMessageSizeLimit accepts negative values, which currently get silently ignored later. This can hide misconfiguration and make behavior non-obvious for callers.

Proposed fix
func WithWebsocketMessageSizeLimit(messageSizeLimit int64) ClientOption {
+	if messageSizeLimit < 0 {
+		panic("negative websocket message size limit")
+	}
 	return optionFunc(func(cfg *clientConfig) {
 		cfg.wsMessageSizeLimit = &messageSizeLimit
 	})
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func WithWebsocketMessageSizeLimit(messageSizeLimit int64) ClientOption {
return optionFunc(func(cfg *clientConfig) {
cfg.wsMessageSizeLimit = &messageSizeLimit
})
func WithWebsocketMessageSizeLimit(messageSizeLimit int64) ClientOption {
if messageSizeLimit < 0 {
panic("negative websocket message size limit")
}
return optionFunc(func(cfg *clientConfig) {
cfg.wsMessageSizeLimit = &messageSizeLimit
})
}
🤖 Prompt for 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.

In `@rpc/client_opt.go` around lines 72 - 75, The WithWebsocketMessageSizeLimit
API accepts negative values which are silently ignored later; update
WithWebsocketMessageSizeLimit to validate messageSizeLimit at the API boundary
by checking if messageSizeLimit < 0 and failing fast (panic with a clear
message) so callers are warned immediately, otherwise continue to set
cfg.wsMessageSizeLimit = &messageSizeLimit; reference the function name
WithWebsocketMessageSizeLimit and the cfg.wsMessageSizeLimit field when making
this change.

Comment thread rpc/server.go
Comment on lines +85 to +87
func (s *Server) SetWebsocketReadLimit(limit int64) {
s.wsReadLimit = limit
}
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard invalid negative websocket read limits.

SetWebsocketReadLimit currently accepts negative values without validation. Add a guard so invalid input cannot silently configure undefined/unintended behavior on the server path.

Proposed fix
func (s *Server) SetWebsocketReadLimit(limit int64) {
+	if limit < 0 {
+		limit = wsDefaultReadLimit
+	}
 	s.wsReadLimit = limit
}
🤖 Prompt for 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.

In `@rpc/server.go` around lines 85 - 87, SetWebsocketReadLimit currently accepts
negative values; add validation in the Server.SetWebsocketReadLimit method so
that if limit is negative it is guarded against (e.g., clamp to 0 or return
early) instead of assigning to s.wsReadLimit; update the method to check limit <
0 and handle by setting s.wsReadLimit = 0 (or leaving existing value) to avoid
silently configuring an invalid read limit.

Added a new function to construct introspection queries for testing maximum query depth. Updated the test to validate that queries at the maximum depth succeed and those exceeding it return the expected error.
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