GuardAPI Logo
GuardAPI
Automated Security Protocol

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

VULNERABLE CODE
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.

SECURE CODE
defmodule MyAppWeb.Plugs.RateLimiter do
  import Plug.Conn
  import Phoenix.Controller

def 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()
end

end 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

System Alert • ID: 7212
Target: Phoenix API
Potential Vulnerability

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.

RUN FREE SECURITY DIAGNOSTIC
GuardLabs Engine: ONLINE

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.