How to fix API Rate Limit Exhaustion
in Phoenix
Executive Summary
API Rate Limit Exhaustion in Phoenix allows attackers to perform Denial of Service (DoS) or credential stuffing by spamming expensive endpoints. Without throttling, your BEAM nodes will prioritize junk traffic, exhausting the Ecto connection pool or CPU cycles. We fix this by implementing a middleware layer using the Hammer library to enforce a token bucket strategy at the Plug level.
The Vulnerable Pattern
defmodule MyAppWeb.AuthController do use MyAppWeb, :controller
def login(conn, %{“user” => user, “pass” => pass}) do # VULNERABILITY: No rate limiting. # An attacker can automate 10,000 requests/sec to brute-force passwords # or crash the database connection pool. case Auth.verify(user, pass) do {:ok, token} -> json(conn, %{token: token}) {:error, _} -> conn |> put_status(401) |> json(%{error: “Unauthorized”}) end end end
The Secure Implementation
The fix moves rate-limiting logic into a custom Plug that executes before the controller action. By using Hammer (backed by Redis or ETS), we track request counts per IP address. If the threshold (5 requests/60s) is exceeded, we return a 429 Too Many Requests status and call `halt(conn)` to prevent the request from ever hitting the expensive authentication logic or the database. This protects the application's availability and mitigates brute-force vectors.
defmodule MyAppWeb.Plugs.RateLimiter do import Plug.Conn import Phoenix.Controllerdef init(opts), do: opts
def call(conn, _opts) do # Identify client by IP or API Key client_id = conn.remote_ip |> Tuple.to_list() |> Enum.join(”.”)
# Limit to 5 requests per 60 seconds case Hammer.check_rate("login_attempt:#{client_id}", 60_000, 5) do {:allow, _count} -> conn {:deny, _limit} -> conn |> put_status(:too_many_requests) |> json(%{error: "Rate limit exceeded. Try again later."}) |> halt() endend end
In your router.ex:
pipeline :api_throtled do plug MyAppWeb.Plugs.RateLimiter end
scope “/api”, MyAppWeb do pipe_through [:api, :api_throtled] post “/login”, AuthController, :login end
Your Phoenix API
might be exposed to API Rate Limit Exhaustion
74% of Phoenix apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.