GuardAPI Logo
GuardAPI
Automated Security Protocol

How to fix JWT Vulnerabilities (Weak Signing, None Algo)
in Plug

Executive Summary

JWT implementation flaws in Elixir/Plug applications typically stem from two vectors: accepting the 'none' algorithm and using weak, guessable secrets. Attackers can bypass authentication by modifying the JWT header to 'alg: none' or brute-forcing weak HMAC keys. In Plug-based apps using Joken or JOSE, you must explicitly enforce signing algorithms and validate signatures before processing claims.

The Vulnerable Pattern

VULNERABLE CODE
defmodule MyAppWeb.AuthPlug do
  import Plug.Conn

def call(conn, _opts) do case get_req_header(conn, “authorization”) do [“Bearer ” <> token] -> # VULNERABILITY: peek_claims/1 skips signature verification entirely # This allows an attacker to provide a JWT with ‘alg: none’ or a fake signature {:ok, claims} = Joken.peek_claims(token) assign(conn, :current_user, claims[“sub”]) _ -> conn |> send_resp(401, “unauthorized”) |> halt() end end end

The Secure Implementation

The fix eliminates the 'none' algorithm exploit by using `verify_and_validate/3` with a pre-configured `Signer`. This ensures that the server only accepts tokens signed with the HS256 algorithm and the server-side secret. By avoiding `peek_claims/1` or generic decoding functions that rely on the token's header to determine the algorithm, we prevent 'Algorithm Switching' attacks. Additionally, using `System.fetch_env!/1` ensures that a strong, unique secret is used in production rather than a default or weak string.

SECURE CODE
defmodule MyAppWeb.AuthPlug do
  import Plug.Conn

Hardcode the expected algorithm and pull the secret from environment variables

@signer Joken.Signer.create(“HS256”, System.fetch_env!(“JWT_SECRET”))

def call(conn, _opts) do with [“Bearer ” <> token] <- get_req_header(conn, “authorization”), # SECURE: verify_and_validate/3 checks the signature using our defined signer {:ok, claims} <- Joken.verify_and_validate(%{}, token, @signer) do assign(conn, :current_user, claims[“sub”]) else {:error, _reason} -> conn |> send_resp(401, “unauthorized”) |> halt() _ -> conn |> send_resp(401, “unauthorized”) |> halt() end end end

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

Your Plug API might be exposed to JWT Vulnerabilities (Weak Signing, None Algo)

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.