HIGH api key exposurephoenixapi keys

Api Key Exposure in Phoenix with Api Keys

Api Key Exposure in Phoenix with Api Keys — how this specific combination creates or exposes the vulnerability

In Phoenix applications, exposing API keys in client-side code or configuration files reachable from the web creates a direct path for unauthorized access and abuse. When API keys are embedded in JavaScript, templates, or environment variables that leak to the browser, any attacker can harvest them and use them to call downstream services, bypass intended rate limits, or exceed quota.

Phoenix endpoints that render configuration values into views or API responses without filtering sensitive fields can unintentionally include keys in JSON payloads served to unauthenticated clients. For example, a debug endpoint returning the entire runtime configuration or a health check that echoes connection parameters may include keys if developers are not careful. Because these endpoints are often unauthenticated or lightly protected, an attacker can probe standard paths such as /debug, /health, or /config to locate keys.

The risk is compounded when keys have broad permissions or are long-lived, resembling secrets stored in plaintext rather than references to secure vaults. An exposed key allows an attacker to act with the same permissions as the service that used it, leading to data exfiltration, unauthorized transactions, or lateral movement within your infrastructure. middleBrick’s Data Exposure and Property Authorization checks specifically flag endpoints that return sensitive server-side values, including patterns that match known key formats, so you can identify and remediate these leaks before an attacker finds them.

During a black-box scan, middleBrick tests unauthenticated attack surfaces and runs checks in parallel, including Data Exposure, to detect whether API keys appear in responses. This is distinct from authentication flaws; even properly authenticated endpoints can leak keys if they include them in payloads or logs that reach the client. Because scanning takes 5–15 seconds, you can quickly validate whether key material is exposed and prioritize fixes based on severity.

Api Keys-Specific Remediation in Phoenix — concrete code fixes

To prevent API key exposure in Phoenix, keep keys out of the client-side and ensure runtime configuration filters sensitive values. Use server-side environment variables and inject only non-sensitive configuration to controllers and views. Never pass raw keys or full configuration maps to templates or JSON responses.

1. Filter keys in controllers and views

When returning configuration for debugging or operational endpoints, explicitly exclude sensitive fields. Instead of dumping the entire configuration map, select only safe keys.

defmodule MyAppWeb.DebugController do
  use MyAppWeb, :controller

  def show(conn, _params) do
    config = Application.get_all_env(:my_app)
    safe_config = Map.take(config, [:app_name, :endpoint_port, :log_level])
    json(conn, %{config: safe_config})
  end
end

2. Use runtime configuration with restricted keys

Configure services using system environment variables and read them at startup, then pass derived, non-sensitive values to your application modules. Avoid storing keys in config files that might be checked into version control or exposed via debug routes.

config :my_app, MyApp.ServiceClient,
  api_key: System.get_env("SERVICE_API_KEY")

# In your client module, use the key internally without exposing it
defmodule MyApp.ServiceClient do
  @api_key Application.get_env(:my_app, __MODULE__)[:api_key]

  def call_external do
    headers = [{"Authorization", "Bearer #{@api_key}"}]
    # perform request internally
  end
end

3. Protect debug and health endpoints

Ensure that endpoints which could echo configuration are either removed in production or protected with authentication and strict authorization. If you must keep them, filter out sensitive keys and restrict access to internal networks or admin roles.

defmodule MyAppWeb.HealthController do
  use MyAppWeb, :controller

  plug MyAppWeb.Plugs.Authorize when action in [:show]

  def show(conn, _params) do
    # Return only status, not configuration
    json(conn, %{status: "ok"})
  end
end

4. Validate and sanitize logs

Ensure your logging configuration does not include API keys. If structured logging is used, redact values that match key patterns before writing events.

config :logger, :console,
  format: "$time $metadata[$level] $message\n",
  metadata: :redaction_fn

defmodule MyAppWeb.Plugs.RedactKeys do
  import Plug.Conn

  def init(opts), do: opts

  def call(conn, _opts) do
    # Example redaction hook; implement pattern replacement for keys
    assign(conn, :redaction_fn, &redact/1)
  end

  defp redact(msg) do
    # Replace API key-like strings in messages
    Regex.replace(~r/API_KEY=[^\s&\"]+/, msg, "API_KEY=[REDACTED]")
  end
end

5. Use vault integration for runtime secrets

For production, retrieve keys from a secure vault at runtime rather than embedding them in releases or config files. Your application should request tokens at startup and keep them in memory, avoiding any controller or view exposure.

defmodule MyApp.SecretProvider do
  def get_api_key do
    # Example: fetch from a vault, cache in application env
    case Cachex.get(:secret_cache, :service_key) do
      {:ok, key} -> key
      :not_found -> fetch_from_vault_and_cache()
    end
  end

  defp fetch_from_vault_and_cache do
    key = VaultClient.get("secret/data/service")["data"]["api_key"]
    Cachex.put(:secret_cache, :service_key, key)
    key
  end
end

Frequently Asked Questions

Can middleBrick detect API key exposure in Phoenix responses?
Yes, middleBrick’s Data Exposure check flags responses that contain patterns resembling API keys, helping you identify unintended leakage in debug, health, or configuration endpoints.
Does exposing an API key in Phoenix require authentication to be a finding?
No. middleBrick tests unauthenticated attack surfaces and flags exposed keys in any response served without requiring authentication, including endpoints that accidentally include keys in JSON or HTML.