Skip to content

M-H11: revert empty signatures on quorum verification#672

Merged
philanton merged 1 commit into
fix/audit-findingsfrom
fix/clearnode-h-11
Apr 10, 2026
Merged

M-H11: revert empty signatures on quorum verification#672
philanton merged 1 commit into
fix/audit-findingsfrom
fix/clearnode-h-11

Conversation

@philanton
Copy link
Copy Markdown
Contributor

@philanton philanton commented Apr 9, 2026

Description

The verifyQuorum helper is called from four app-session RPC endpoints: create_app_session, submit_app_state, submit_deposit_state, and rebalance_app_sessions. In each case, quorum_sigs is user-controlled. Inside verifyQuorum, each signature is decoded from hex and the first byte is read immediately to determine the signer type

    for _, sigHex := range signatures {
        sigBytes, err := hexutil.Decode(sigHex)
        if err != nil {
            return rpc.Errorf("failed to decode signature: %v", err)
        }

        sigType := app.AppSessionSignerTypeV1(sigBytes[0])
        userWallet, err := appSessionSignerValidator.Recover(data, sigBytes)

This is unsafe because hexutil.Decode("0x") returns an empty slice without error. Supplying quorum_sigs = ["0x"] causes sigBytes[0] to panic with an out-of-range access instead of returning a validation error.
The same helper is also used by app updates, deposits, and rebalance flows, so the bug is reachable through multiple app-session RPC methods. The panic occurs in the request processing path and is not recovered there, so a single malformed request can terminate the service process.
Consequently, any remote caller who can reach these endpoints can cause a denial of service with a malformed signature.

Summary by CodeRabbit

  • Bug Fixes

    • Added validation to detect and report empty signatures with their position index for improved error diagnostics.
  • Refactor

    • Reordered quorum verification to execute earlier in the session creation workflow.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0ad28055-014e-437e-8c41-7911bc116b23

📥 Commits

Reviewing files that changed from the base of the PR and between 037bb72 and 20f607a.

📒 Files selected for processing (2)
  • clearnode/api/app_session_v1/create_app_session.go
  • clearnode/api/app_session_v1/handler.go

📝 Walkthrough

Walkthrough

The pull request modifies app session creation to verify quorum earlier in the transaction flow and adds validation for empty signatures. Specifically, verifyQuorum() is now called immediately after action gateway verification and before creating the app session record, and the quorum verification loop now rejects empty signature bytes with an indexed error.

Changes

Cohort / File(s) Summary
CreateAppSession Flow Reordering
clearnode/api/app_session_v1/create_app_session.go
Moved h.verifyQuorum(...) execution to occur immediately after h.actionGateway.AllowAction(...) and before tx.CreateAppSession(appSession), advancing the verification step in the transaction sequence.
Quorum Signature Validation
clearnode/api/app_session_v1/handler.go
Enhanced verifyQuorum loop to track signature index and validate decoded signature bytes, returning an RPC error with the index when empty signatures are encountered.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • ihsraham
  • dimast-x

Poem

🐰 A quorum check hops to the front of the line,
Empty signatures caught with an index divine,
Verification flows earlier, trusty and tight,
App sessions created with cryptographic might!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: reverting/handling empty signatures in quorum verification to fix a safety bug.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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/clearnode-h-11

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.

@nksazonov
Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

✅ Actions performed

Review triggered.

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.

@philanton philanton merged commit 4001fc0 into fix/audit-findings Apr 10, 2026
3 checks passed
@philanton philanton deleted the fix/clearnode-h-11 branch April 10, 2026 12:32
nksazonov added a commit that referenced this pull request Apr 16, 2026
H-H01: fix(contracts): disallow challenge with CLOSE or FIN_MIG intents (#631)

H-M01: fix(contracts/ChannelHub): remove transferred amount check (#636)

fix(contracts/ChannelHub): allow unblocking escrow ops after migration (#637)

M-C01: feat(contracts): add token check between states (#639)

H-L03: fix(contracts/ChannelHub): skip disputed escrow during purge (#640)

M-H04: feat(contracts/ChannelHub): purge during escrow challenge finalization, count both skip and purge (#641)

M-M02: fix(contracts): require zero allocs on close (#643)

M-C02: fix(rpc/core): apply finalize escrow deposit correctly (#644)

H-L02: fix(contracts/ChannelHub): revert on withdrawFromVault failure (#651)

M-H03: fix(clearnode): log correct fields on failure (#647)

M-C03: fix(pkg/core): disallow negative amount transitions (#645)

H-L01: fix(contracts/ChannelHub): add CH address to prevent val addition replay (#650)

M-H06(clearnode): restrict max channel challenge duration (#654)

M-M03(clearnode): revert EscrowLock on insufficient home user balance (#655)

M-M04(clearnode): support default signer even if it is not approved (#656)

M-M05(clearnode): require correct intent on FinalizeEscrowWithdrawal (#657)

M-M09: reject asset decimals exceeding its token's decimals (#659)

M-L01: return correct errors during state advancement validation (#660)

M-L03: limit number of related ids per session key state (#662)

M-I02: normalize input hex addresses (#663)

M-H01: feat(contracts/ChannelHub): restrict to one node (#649)

M-H07: fix(contracts/ChannelHub): emit stored, not arbitrary candidate state (#664)

M-I01: feat(contracts/ChannelHub): remove updateLastState flag (#665)

H-L06: fix(contracts/ChannelHub): remove payable from methods, clarify in create (#666)

H-L09: feat(contracts/ChannelEngine): add non-home migration version check (#669)

YNU-839: fix blockchain listener lifecycle (#658)

M-H09: use channel signer for all channel state node sigs (#667)

H-L07: fix(contracts/ChannelHub): restrict createChannel to non-existing channels (#668)

H-I02: docs(contracts): add a note that rebasing tokens are not supported (#670)

H-I03: fix(contracts/ChannelHub): use CIE pattern in depositToHub (#671)

M-H11: revert empty signatures on quorum verification (#672)

M-H11: reject issuance of receiver state during escrow ops (#674)

H-I01: docs(contracts): note that fee-on-transfer tokens are not supported (#675)

M-L04: docs: mention liquidity monitoring (#677)

fix(contracts/ChannelHub): fix initialize escrow deposit dos (#679)

M-H08: enforce strict transition ordering after MutualLock and EscrowLock (#680)

fix: run forge fmt (#681)

M-L05: docs(contracts): document native token deposits (#685)

fix(clearnode): resolve a set of audit findings (#686)

M-H13: feat(contract): add validateChallengeSignature, revert in SK validator (#688)
@coderabbitai coderabbitai Bot mentioned this pull request May 20, 2026
7 tasks
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.

3 participants