Skip to content

Add input size limits to prevent exponential computation#505

Open
rbtying wants to merge 3 commits into
masterfrom
claude/autopatch-scan-3a6b5db9-vuln-299334-a5aIa
Open

Add input size limits to prevent exponential computation#505
rbtying wants to merge 3 commits into
masterfrom
claude/autopatch-scan-3a6b5db9-vuln-299334-a5aIa

Conversation

@rbtying
Copy link
Copy Markdown
Owner

@rbtying rbtying commented Mar 20, 2026

Summary

This PR adds safeguards to prevent algorithmic complexity attacks by introducing maximum size limits for card decomposition operations. The changes protect against super-exponential blowup in partition computation while maintaining normal functionality for reasonable inputs.

Key Changes

  • Added MAX_DECOMPOSITION_SIZE constant (20 cards) in ordered_card.rs to cap inputs to find_tuple_partitions, preventing exponential growth in partition enumeration (p(20)=627 vs p(100)≈190M)
  • Added early return in full_decomposition_ordering that returns trivial decomposition (all singles) for inputs exceeding the limit
  • Added MAX_TRICK_FORMAT_SIZE constant (20 cards) in wasm-rpc-impl/lib.rs to validate trick format sizes at the API boundary
  • Added validation in decompose_trick_format that rejects requests with trick formats exceeding the maximum size
  • Improved mutex error handling across all cache operations by using unwrap_or_else(|e| e.into_inner()) instead of unwrap(), allowing recovery from poisoned locks

Implementation Details

  • The 20-card limit is practical for real gameplay (players*2 decks, typically ≤20 cards) while preventing pathological inputs
  • Trivial decomposition fallback ensures graceful degradation rather than panics or timeouts
  • Mutex poison recovery allows the system to continue operating even if a thread panics while holding a lock
  • All three caches (FULL_DECOMPOSITION_CACHE, GROUP_CACHE, SEQUENTIAL_ASSIGNMENT_CACHE) now use consistent error handling

https://claude.ai/code/session_018crD7az1p5jRzxzCwqMQuP

claude added 3 commits March 20, 2026 20:51
…ation

The unauthenticated /api/rpc endpoint accepts DecomposeTrickFormat requests
with attacker-controlled TrickUnit count values. The find_tuple_partitions
function computes all integer partitions recursively, which grows
super-exponentially (p(100) ≈ 190M). Large count values exhaust CPU/memory,
and stack overflows poison global mutex caches permanently.

Changes:
- Add MAX_DECOMPOSITION_SIZE (54) bound in full_decomposition_ordering to
  cap partition computation at one full deck size
- Add input validation in decompose_trick_format RPC handler to reject
  trick formats exceeding the maximum size before processing
- Replace .lock().unwrap() with .lock().unwrap_or_else(|e| e.into_inner())
  on all three global cache mutexes to recover from poisoned state

https://claude.ai/code/cse_018crD7az1p5jRzxzCwqMQuP
54 was based on deck size, but the relevant bound is num_decks (max
players*2), which caps how many copies of a single card can exist.
20 covers even 10-player games while keeping partition counts trivial
(p(20)=627 vs p(54)≈219K).

https://claude.ai/code/cse_018crD7az1p5jRzxzCwqMQuP
Provides more headroom for games with many players/decks while
p(32)=8349 remains computationally trivial.

https://claude.ai/code/cse_018crD7az1p5jRzxzCwqMQuP
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