Skip to content

Fix DoS vulnerability in play_card API by adding rate limiting#2629

Open
xovishnukosuri wants to merge 1 commit intoOWASP:masterfrom
xovishnukosuri:fix/play-card-api-rate-limiting
Open

Fix DoS vulnerability in play_card API by adding rate limiting#2629
xovishnukosuri wants to merge 1 commit intoOWASP:masterfrom
xovishnukosuri:fix/play-card-api-rate-limiting

Conversation

@xovishnukosuri
Copy link

Summary

  • Adds rate limiting to the :api pipeline via RateLimiterPlug to protect the play_card endpoint from DoS attacks (fixes 🚨Security Issue: play_card API Vulnerable to DoS Attack - 29% Success Rate Confirmed #2559)
  • Introduces a new :play_card action in RateLimiter GenServer with a default limit of 10 requests per 60-second window per IP (configurable via RATE_LIMIT_PLAY_CARD_LIMIT and RATE_LIMIT_PLAY_CARD_WINDOW env vars)
  • Makes RateLimiterPlug action-configurable via plug options, returning JSON 429 responses for API endpoints while maintaining backwards-compatible plain-text responses for the browser pipeline

Details

The vulnerability existed because the :api pipeline in router.ex had no RateLimiterPlug, unlike the :browser pipeline. This allowed attackers to send unlimited concurrent requests to PUT /api/games/:game_id/players/:player_id/card, exhausting database connections and corrupting game state through race conditions (29% of 100 simultaneous requests succeeded per the issue report).

Files changed:

  • lib/copi_web/router.ex — Add RateLimiterPlug to :api pipeline with action: :play_card
  • lib/copi/rate_limiter.ex — Add :play_card action with limit/window config
  • lib/copi_web/plugs/rate_limiter_plug.ex — Make action configurable, add JSON 429 responses for non-connection actions
  • test/copi/rate_limiter_test.exs — Add tests for play_card rate limiting and config

Test plan

  • Verify existing rate_limiter_test.exs tests pass (backwards compatibility of :connection action)
  • Verify new play_card rate limit test passes (blocks after 10 requests in 60s window)
  • Verify rate_limiter_plug_test.exs tests pass (plug still defaults to :connection with no opts)
  • Verify api_controller_test.exs tests pass (play_card endpoint still works under limit)
  • Manual test: confirm 429 JSON response after exceeding play_card limit via API

🤖 Generated with Claude Code

The API pipeline lacked rate limiting protection, allowing unlimited
concurrent requests to the play_card endpoint. This could exhaust database
connections and corrupt game state. Fix adds the existing RateLimiterPlug
to the :api pipeline with a new :play_card action (10 requests/60s per IP),
makes the plug action-configurable, and returns proper JSON 429 responses
for API endpoints.

Closes OWASP#2559

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

🚨Security Issue: play_card API Vulnerable to DoS Attack - 29% Success Rate Confirmed

1 participant