Skip to content

Bug: play_card API endpoint allows playing cards on unstarted or finished games #2631

@immortal71

Description

@immortal71

Describe the bug

The PUT /api/games/:game_id/players/:player_id/card endpoint in api_controller.ex has no game lifecycle guard. It only checks whether the card was already played and whether the player has already played in the current round — it never checks game.started_at or game.finished_at.

This means a script can call the API to play cards before the game starts (lobby phase, started_at == nil) or after the game ends (finished_at != nil), corrupting the game state.

Affected file

copi.owasp.org/lib/copi_web/controllers/api_controller.ex

Code snippet

def play_card(conn, %{"game_id" => game_id, "player_id" => player_id, "dealt_card_id" => dealt_card_id}) do
  with {:ok, game} <- Game.find(game_id) do
    ...
    current_round = game.rounds_played + 1
    cond do
      dealt_card.played_in_round ->
        conn |> put_status(:not_acceptable) |> json(%{"error" => "Card already played"})
      Enum.find(...) ->
        conn |> put_status(:forbidden) |> json(%{"error" => "Player already played a card in this round"})
      true ->
        # No check: is the game started? Has it finished?
        dealt_card = Ecto.Changeset.change dealt_card, played_in_round: current_round
        Copi.Repo.update dealt_card

Expected behavior

The endpoint should reject card plays with 422 Unprocessable Entity if:

  • game.started_at == nil — game has not started yet
  • game.finished_at != nil — game has already ended

Steps to reproduce

# Play a card via the API *before* start_game is called
curl -X PUT https://copi.owasp.org/api/games/:game_id/players/:player_id/card \
     -H "Content-Type: application/json" \
     -d '{"dealt_card_id": "<id>"}'
# Returns 200 and records the play even though the game hasn't started

Additional context

Issue #2568 covers the equivalent gap in the toggle_vote LiveView handler. This is the same missing guard in the REST API endpoint for card plays.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions