HIGH brute force attackphoenixhmac signatures

Brute Force Attack in Phoenix with Hmac Signatures

Brute Force Attack in Phoenix with Hmac Signatures — how this specific combination creates or exposes the vulnerability

A brute force attack against an API using Hmac Signatures in Phoenix typically targets the timestamp and nonce components of the signing process. Hmac Signatures rely on a shared secret to generate a hash that includes parameters such as the HTTP method, request path, query parameters, headers, and a timestamp. If the server does not enforce strict constraints on the timestamp window and nonce uniqueness, an attacker can rapidly iterate through possible timestamps and nonces to find a valid signature.

In Phoenix, this can occur when a request is accepted even if its timestamp is significantly out of sync with the server’s time. For example, an endpoint that only checks that the timestamp is not in the future, but allows a large skew window (e.g., several minutes or hours), enables an attacker to brute force the timestamp within that window. Combined with a predictable or insufficiently random nonce, this can allow an attacker to replay requests or guess valid signatures.

The attack flow often involves intercepting a valid request, then modifying the timestamp and nonce while systematically submitting requests to the Phoenix endpoint. Because the Hmac signature is verified by recomputing the hash using the provided parameters and the shared secret, an attacker does not need to know the secret if they can find a valid timestamp–nonce pair that passes the server’s validation logic. This is especially problematic when rate limiting is absent or weak, allowing many attempts without being blocked.

Such vulnerabilities map to the Authentication and BOLA/IDOR checks performed by middleBrick, which detects weak timestamp handling and missing nonce enforcement during unauthenticated scans. The scanner identifies whether the API accepts requests with timestamps that deviate excessively from server time and whether replay protections are insufficient.

Hmac Signatures-Specific Remediation in Phoenix — concrete code fixes

To remediate brute force risks with Hmac Signatures in Phoenix, enforce a tight timestamp window and require unique, non-repeating nonces. Below are concrete, realistic code examples that demonstrate secure validation in a Phoenix controller and a plug that can be reused across endpoints.

1. Shared Secret and Signature Verification

Ensure the shared secret is stored securely, for example via environment variables, and never logged. Use constant-time comparison when needed.

defmodule MyApp.Hmac do
  @moduledoc """
  Utilities for Hmac Signature verification with strict timestamp and nonce checks.
  """
  @timestamp_tolerance_ms 30_000       # 30 seconds tolerance
  @max_nonce_age_s 300                 # reject nonces older than 5 minutes

  def verify_signature(params, headers, secret) do
    with {:ok, timestamp} <- get_timestamp(headers),
         {:ok, nonce} <- get_nonce(headers),
         true <- within_time_window?(timestamp),
         true <- nonce_not_recent?(nonce),
         signature = generate_signature(params, timestamp, nonce, secret),
         true <- constant_time_compare(signature, get_signature(headers)) do
      {:ok, %{timestamp: timestamp, nonce: nonce}}
    else
      _ -> {:error, :invalid_signature}
    end
  end

  defp get_timestamp(headers) do
    case List.keyfind(headers, "x-timestamp", 0) do
      {"x-timestamp", ts} -> {value, _} = Integer.parse(ts); {:ok, value}
      _ -> {:error, :missing_timestamp}
    end
  end

  defp get_nonce(headers) do
    case List.keyfind(headers, "x-nonce", 0) do
      {"x-nonce", nonce} -> {:ok, nonce}
      _ -> {:error, :missing_nonce}
    end
  end

  defp generate_signature(params, timestamp, nonce, secret) do
    string_to_sign = "GET\n/api/resource\n" <> URI.encode_query(params) <> "\n" <> to_string(timestamp) <> "\n" <> nonce
    :crypto.mac(:hmac, :sha256, secret, string_to_sign)
    |> Base.encode16(case: :lower)
  end

  defp constant_time_compare(a, b) when is_binary(a) and is_binary(b), do: :crypto.secure_compare(a, b)
  defp constant_time_compare(_, _), do: false
end

2. Plug to Reject Invalid Timestamps and Replayed Nonces

Use a plug that validates the timestamp and nonce before the request reaches your router or controller. Store recently seen nonces in a transient in-memory set (for single-node) or a distributed cache like Redis for multi-node setups, with a TTL slightly longer than @max_nonce_age_s.

defmodule MyApp.Plugs.HmacAuth do
  use Plug.Builder

  plug :fetch_headers
  plug :validate_timestamp_and_nonce

  defp validate_timestamp_and_nonce(conn, _opts) do
    secret = System.get_env("HMAC_SECRET")
    with {:ok, auth} <- MyApp.Hmac.verify_signature(conn.params, conn.req_headers, secret) do
      # Optionally store nonce with TTL to prevent replays within the tolerance window
      MyApp.NonceCache.put(auth.nonce, :timer.now(), :timer.seconds(@max_nonce_age_s))
      conn
    else
      {:error, _} ->
        conn
        |> Plug.Conn.put_resp_content_type("application/json")
        |> Plug.Conn.send_resp(401, Jason.encode!(%{error: "unauthorized"}))
        |> Plug.Conn.halt()
    end
  end
end

3. Enforce a Strict Timestamp Window

Reject requests where the timestamp is older or too far in the future. This prevents attackers from brute forcing old or future timestamps.

defmodule MyApp.Hmac do
  # ... previous code ...

  defp within_time_window?(timestamp) do
    now = DateTime.utc_now() |> DateTime.to_unix(:millisecond)
    abs(timestamp - now) <= @timestamp_tolerance_ms
  end
end

4. Require Server-Side Nonce Tracking

Ensure each nonce is used only once within the acceptable time window. For distributed systems, use a shared store with short TTL to avoid replay across nodes.

defmodule MyApp.NonceCache do
  @ttl_seconds 300

  def put(nonce, timestamp, ttl \\ @ttl_seconds) do
    # Example using Agent or Redis; adapt to your infrastructure
    Agent.update(__MODULE__, &Map.put(&1, nonce, timestamp))
    # Schedule cleanup after ttl
  end

  def recent_nonces do
    Agent.get(__MODULE__, & &1)
  end
end

By combining a narrow timestamp tolerance, strict nonce uniqueness, and server-side validation, you significantly reduce the feasibility of brute forcing Hmac Signatures in Phoenix. These measures align with security checks that middleBrick performs, highlighting weak authentication handling and replay risks.

Frequently Asked Questions

What does middleBrick detect when scanning Hmac Signatures in Phoenix?
middleBrick detects weak timestamp handling, missing or predictable nonces, and insufficient replay protection, which can enable brute force and replay attacks.
Can middleBrick fix Hmac Signature vulnerabilities in Phoenix?
middleBrick detects and reports findings with remediation guidance, but it does not fix, patch, block, or remediate. Developers should apply server-side timestamp and nonce validation as shown in the code examples.