GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix Broken User Authentication
in Plug

Executive Summary

Authentication in Elixir/Plug environments is frequently compromised when developers treat client-provided cookies as trusted server-side state. Broken User Authentication (OWASP A07:2021) occurs when session identifiers are not cryptographically signed or encrypted, allowing an attacker to manipulate the 'user_id' or 'role' directly in the browser to escalate privileges or impersonate users.

The Vulnerable Pattern

VULNERABLE CODE
defmodule MyApp.VulnerableAuth do
  import Plug.Conn

def init(opts), do: opts

def call(conn, _opts) do # FAIL: Reading raw, unsigned cookies directly from the request # An attacker can set ‘user_id’ to ‘1’ in their browser to become admin user_id = conn.req_cookies[“user_id”]

case user_id do
  nil -> 
    conn |> send_resp(401, "Unauthorized") |> halt()
  id -> 
    assign(conn, :current_user, id)
end

end end

The Secure Implementation

The vulnerability exists because `conn.req_cookies` provides raw access to client-side data which is trivial to forge. The secure implementation utilizes `Plug.Session` which wraps `Plug.Crypto`. By using `get_session/2`, the application ensures the session cookie has been signed with the server's `secret_key_base`. If an attacker attempts to modify the `user_id`, the signature verification will fail, and Plug will treat the session as empty. Always ensure `http_only: true` and `secure: true` flags are set in your session configuration to mitigate XSS and Man-in-the-Middle (MITM) attacks.

SECURE CODE
defmodule MyApp.SecureAuth do
  import Plug.Conn

In your endpoint/router, configure Plug.Session properly:

plug Plug.Session,

store: :cookie,

key: “_secure_session_key”,

signing_salt: “S3cur3_S4lt”,

encryption_salt: “Enc_S4lt”

def init(opts), do: opts

def call(conn, _opts) do # SUCCESS: get_session/2 retrieves data from a cryptographically signed/encrypted cookie # The payload is verified against the application’s secret_key_base case get_session(conn, :user_id) do nil -> conn |> send_resp(401, “Unauthorized”) |> halt() user_id -> assign(conn, :current_user, user_id) end end end

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

Your Plug API might be exposed to Broken User Authentication

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.