Skip to content

fix(cosmossdk): reject malformed tx history cursor at request boundary#1279

Merged
kaladinlight merged 1 commit into
developfrom
fix/cosmos-cursor-nil-state
Jun 12, 2026
Merged

fix(cosmossdk): reject malformed tx history cursor at request boundary#1279
kaladinlight merged 1 commit into
developfrom
fix/cosmos-cursor-nil-state

Conversation

@0xApotheosis

@0xApotheosis 0xApotheosis commented Jun 12, 2026

Copy link
Copy Markdown
Member

Description

A caller-supplied cursor is unmarshalled into the server-initialized pagination state. json.Unmarshal stores a JSON null state value as a nil *CursorState. filterByCursor later iterates Cursor.State and dereferences each entry — and that dereference runs in an errgroup worker goroutine, so the resulting panic is not recovered by net/http (it only recovers the request handler goroutine). One crafted, unauthenticated request therefore crashes the whole process instead of failing a single request.

This validates the cursor at the request boundary so a malformed value can never reach the crash path:

  • ValidatePagingParams decodes the cursor and rejects any nil state entry, returning 400 Bad Request before any source state is built or worker goroutine is spawned.
  • Cursor.Decode stays a pure decode; filterByCursor/history.go are left untouched.

Verification

Didn't run go build/tests locally per the repo CLAUDE.md (CI handles build validation). Well-formed cursors are unaffected; only structurally-invalid cursors (bad base64/JSON or a null state entry) now get a 400 instead of reaching pagination.

@0xApotheosis
0xApotheosis requested a review from a team as a code owner June 12, 2026 05:17
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

ValidatePagingParams adds defensive validation to cursor query parameters. After decoding a cursor, the function now checks the decoded Cursor.State map for nil entries and rejects cursors containing any nil values with HTTP 400 Bad Request, preventing potential nil-pointer dereferences downstream.

Changes

Cursor State Validation

Layer / File(s) Summary
Nil-state cursor validation
go/shared/cosmossdk/api.go
ValidatePagingParams checks decoded cursor states for nil entries and returns HTTP 400 with an "invalid cursor" error if any source state is nil, guarding against downstream nil-pointer dereferences.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit hops through cursor streams,
Checking each state—no nil in dreams,
Four hundred's thrown when nil is found,
Safe pagination all around! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title 'fix(cosmossdk): reject malformed tx history cursor at request boundary' directly describes the main change—validating cursors at the request boundary to reject malformed ones with nil entries.

✏️ 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/cosmos-cursor-nil-state

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.

A caller-controlled cursor with a null state value (e.g. {"state":{"x":null}})
decodes to a nil *CursorState entry. That entry is later dereferenced in a
filterByCursor errgroup worker goroutine, where the panic is not recovered by
net/http (it only recovers the handler goroutine) and crashes the process.

Validate the decoded cursor in ValidatePagingParams and return 400 Bad Request
before any source state is built or worker goroutine is spawned, so a malformed
cursor can never reach the crash path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kaladinlight
kaladinlight force-pushed the fix/cosmos-cursor-nil-state branch from 8f0945c to 85a36fc Compare June 12, 2026 22:57
@kaladinlight kaladinlight changed the title fix(cosmossdk): guard nil cursor state in tx history pagination fix(cosmossdk): reject malformed tx history cursor at request boundary Jun 12, 2026
@kaladinlight
kaladinlight merged commit 515bc55 into develop Jun 12, 2026
3 checks passed
@kaladinlight
kaladinlight deleted the fix/cosmos-cursor-nil-state branch June 12, 2026 23:02
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.

2 participants