Skip to content

feat(flexible-outcalls): CON-1709 harden ResponsesTooLarge validation with all-seen-shares proof#9860

Merged
fspreiss merged 13 commits intomasterfrom
fspreiss/CON-1709-fix-responses-too-large
Apr 16, 2026
Merged

feat(flexible-outcalls): CON-1709 harden ResponsesTooLarge validation with all-seen-shares proof#9860
fspreiss merged 13 commits intomasterfrom
fspreiss/CON-1709-fix-responses-too-large

Conversation

@fspreiss
Copy link
Copy Markdown
Contributor

Strengthens the ResponsesTooLarge error for flexible HTTP outcalls to prevent a malicious block proposer from fabricating the error by selectively omitting small OK shares.

  • Renamed metadata_sharesall_seen_shares in FlexibleCanisterHttpError::ResponsesTooLarge and the corresponding protobuf message, so the error now carries all seen shares (both OK and reject), not just a subset.
  • Updated the builder (find_flexible_result) to emit all OK and reject shares into all_seen_shares.
  • Rewrote the validator logic to use is_reject (from CON-1708) to partition shares, compute num_unseen and min_known_ok_needed, and verify that the smallest set of OK responses genuinely exceeds MAX_CANISTER_HTTP_PAYLOAD_SIZE. An early check rejects payloads with too few OK shares before computing sizes.
  • Replaced FlexibleInsufficientMetadataShareCount with the more descriptive FlexibleResponsesTooLargeInsufficientEvidence error variant.
  • Added comprehensive validation tests: mixed OK/reject shares, unseen committee members, attack-vector scenarios (committee members omitted), and insufficient OK share counts.

Attack vector closed

Previously, a malicious proposer could craft a ResponsesTooLarge error by including only a few hand-picked large OK shares while omitting committee members who submitted small responses. The validator would check only the provided shares and accept the error as valid.

Now, the validator computes num_unseen = committee_size - all_seen_shares.len() and min_known_ok_needed = min_responses - num_unseen. Since unseen members could have submitted zero-size OK responses, the validator conservatively assumes they did. A proposer who omits members increases num_unseen, which lowers min_known_ok_needed, making it harder to prove responses are too large—the opposite of what an attacker wants.

Test plan

  • flexible_build_responses_too_large — builder emits all 4 OK shares
  • flexible_build_responses_too_large_with_rejects_reducing_unseen — builder emits 3 OK + 2 reject shares
  • flexible_error_responses_too_large_valid — all committee members with huge OK → accepted
  • flexible_error_responses_too_large_valid_with_unseen_members — legitimate error with 1 unseen member → accepted
  • flexible_error_responses_too_large_valid_with_mixed_ok_and_reject — 2 huge OK + 2 reject, all seen → accepted
  • flexible_error_responses_too_large_invalid_when_small — small OK shares + high unseen → rejected (min_known_ok_needed=0)
  • flexible_error_responses_too_large_invalid_when_committee_members_omitted — attacker omits members, num_unseen defeats the claim → rejected
  • flexible_error_responses_too_large_too_few_ok_shares — not enough OK shares for min_known_ok_needed → InsufficientEvidence
  • Existing tests for duplicate signers, callback mismatch, non-committee signers, registry version mismatch, and invalid signatures continue to pass

@github-actions github-actions bot added the feat label Apr 14, 2026
@fspreiss fspreiss marked this pull request as ready for review April 14, 2026 12:46
@fspreiss fspreiss requested review from a team as code owners April 14, 2026 12:46
Base automatically changed from fspreiss/CON-1708-add-is_reject-to-metadata to master April 14, 2026 13:20
@fspreiss fspreiss requested a review from a team as a code owner April 14, 2026 13:20
@fspreiss fspreiss requested a review from eichhorl April 14, 2026 13:41
Comment thread rs/https_outcalls/consensus/src/payload_builder/utils.rs
Comment thread rs/https_outcalls/consensus/src/payload_builder.rs Outdated
Comment thread rs/https_outcalls/consensus/src/payload_builder.rs Outdated
Comment thread rs/https_outcalls/consensus/src/payload_builder/utils.rs Outdated
Comment thread rs/https_outcalls/consensus/src/payload_builder/tests.rs Outdated
@fspreiss fspreiss enabled auto-merge April 15, 2026 09:05
@fspreiss fspreiss added this pull request to the merge queue Apr 15, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Apr 16, 2026
@fspreiss fspreiss added this pull request to the merge queue Apr 16, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 16, 2026
@fspreiss fspreiss added this pull request to the merge queue Apr 16, 2026
Merged via the queue into master with commit cdc89c1 Apr 16, 2026
62 of 64 checks passed
@fspreiss fspreiss deleted the fspreiss/CON-1709-fix-responses-too-large branch April 16, 2026 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants