You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The start_game event handler in GameLive.Show lacks transaction protection when dealing cards to players. If a database error occurs partway through the card-dealing loop, the game enters a corrupted state with some players having cards while others have none, making the game unplayable.
Note: While reviewing issue #2335 (which addresses the ArithmeticError from zero players), I realized it does not solve this data integrity problem. Even with proper player validation, database failures during card dealing will still corrupt game state.
# Deal cards to players in round-robin fashionall_cards|>Enum.with_index()|>Enum.each(fn{card,i}->Copi.Repo.insert!(%DealtCard{card_id: card.id,player_id: Enum.at(players,rem(i,player_count)).id})end)
Problem Analysis
Issue 1: No Transaction Wrapping
The card dealing operation is not wrapped in a database transaction. If dealing fails at any point:
Already-dealt cards remain in the database
Remaining cards are never dealt
Game state becomes inconsistent and unplayable
Issue 2: Using insert! Instead of insert
The code uses Repo.insert! which raises an exception on any failure, causing the LiveView to crash. This provides no opportunity for error handling or rollback.
Issue 3: No Rollback Mechanism
Without transaction protection, there is no way to roll back partial operations when errors occur.
Scenarios That Trigger Data Corruption
Database connection timeout - Connection drops after dealing 30 of 52 cards
Disk space exhaustion - Database runs out of space mid-operation
ASVS V2.3.3: "Verify that transactions are being used at the business logic level such that either a business logic operation succeeds in its entirety or it is rolled back to the previous correct state."
Description
The
start_gameevent handler inGameLive.Showlacks transaction protection when dealing cards to players. If a database error occurs partway through the card-dealing loop, the game enters a corrupted state with some players having cards while others have none, making the game unplayable.Note: While reviewing issue #2335 (which addresses the ArithmeticError from zero players), I realized it does not solve this data integrity problem. Even with proper player validation, database failures during card dealing will still corrupt game state.
Location
File:
copi.owasp.org/lib/copi_web/live/game_live/show.ex(lines 76-83)Vulnerable Code
Problem Analysis
Issue 1: No Transaction Wrapping
The card dealing operation is not wrapped in a database transaction. If dealing fails at any point:
Issue 2: Using insert! Instead of insert
The code uses
Repo.insert!which raises an exception on any failure, causing the LiveView to crash. This provides no opportunity for error handling or rollback.Issue 3: No Rollback Mechanism
Without transaction protection, there is no way to roll back partial operations when errors occur.
Scenarios That Trigger Data Corruption
Example Corruption Scenario
Setup: Game with 3 players, 52 cards to deal
Failure Point: Database connection timeout after inserting 30 cards
Result:
Reproduction Steps
Impact
Related Files
lib/copi_web/live/game_live/show.ex(lines 54-101)lib/copi/cornucopia/dealt_card.expriv/repo/migrations/20210522185023_create_dealt_cards.exsReferences