GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Unrestricted Resource Consumption
in Plug

Executive Summary

Unrestricted resource consumption in Elixir/Plug apps is a fast track to a DoS. If you fail to cap body sizes, an attacker can flood your BEAM node with massive payloads, triggering the OOM killer or saturating process memory. In the Erlang VM, while processes are isolated, a single massive binary allocation can still compromise node stability. You must enforce strict limits at the parser level to drop malicious streams before they exhaust your heap.

The Vulnerable Pattern

VULNERABLE CODE
defmodule Router do
  use Plug.Router

VULNERABLE: No length limit specified.

Plug.Parsers defaults to 8MB, but many devs override or ignore it,

and custom implementations often read the whole stream blindly.

plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: [”/”], json_decoder: Jason

plug :match plug :dispatch

post “/upload” do # Manual body reading without limits is even worse {:ok, body, conn} = Plug.Conn.read_body(conn) send_resp(conn, 200, “Data received”) end end

The Secure Implementation

The vulnerability stems from trusting the client's Content-Length header or lack thereof. In the vulnerable example, `Plug.Parsers` or a raw `read_body/1` call can be exploited by sending a multi-gigabyte stream that the server attempts to load into memory. The fix involves two layers: 1. Setting the `:length` option in `Plug.Parsers` to globally reject oversized payloads with a 413 Request Entity Too Large error. 2. When using `Plug.Conn.read_body/2` directly, always provide a `:length` (maximum total bytes) and `:read_length` (bytes to read per iteration). This ensures the BEAM process handling the request is terminated or the request is rejected before it can impact the system's global memory pool.

SECURE CODE
defmodule Router do
  use Plug.Router

SECURE: Explicitly define the :length option (in bytes).

This prevents the parser from consuming more than 5MB.

plug Plug.Parsers, parsers: [:urlencoded, :multipart, :json], pass: [”/”], json_decoder: Jason, length: 5_000_000

plug :match plug :dispatch

post “/upload” do # SECURE: Enforce length and read_length during manual reads. case Plug.Conn.read_body(conn, length: 5_000_000, read_length: 1_000_000) do {:ok, body, conn} -> send_resp(conn, 200, “Safe”) {:more, _partial_body, conn} -> send_resp(conn, 413, “Payload Too Large”) {:error, _reason} -> send_resp(conn, 400, “Bad Request”) end end end

System Alert • ID: 4595
Target: Plug API
Potential Vulnerability

Your Plug API might be exposed to Unrestricted Resource Consumption

74% of Plug 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.