Container Escape in Phoenix with Bearer Tokens
Container Escape in Phoenix with Bearer Tokens — how this specific combination creates or exposes the vulnerability
A container escape in Phoenix involving bearer tokens typically occurs when an API endpoint running in a containerized environment inadvertently exposes token validation or introspection endpoints, or when tokens are accepted in ways that allow an attacker to break out of the container’s network or process isolation. Phoenix here refers to a runtime or framework context where services are containerized and rely on bearer tokens for authorization. The vulnerability arises when the container boundary is not strictly enforced and the bearer token mechanism is misconfigured or insufficiently isolated.
One common pattern is an endpoint that echoes or returns the submitted token, either for debugging or introspection. If such an endpoint is reachable from within the container and is not properly scoped, an attacker who obtains a valid bearer token can use it not only for authorization bypass but also to probe internal services that are bound to localhost or exposed via shared network namespaces. Because the container may share kernel namespaces or have relaxed security options, a token accepted by a misrouted handler can be leveraged to trigger SSRF, local privilege escalation, or access to the host filesystem, effectively achieving container escape.
Another vector involves overly permissive CORS and proxy configurations combined with bearer token usage. If CORS allows origins that an attacker controls and the API forwards requests using the submitted bearer token, an authenticated session can be abused to make the compromised container act as a pivot to reach internal metadata services (e.g., cloud instance metadata at 169.254.169.254). This can lead to token exfiltration or lateral movement. The key insight is that the bearer token itself is not unsafe; it is the interaction with container networking, trust boundaries, and exposed introspection or debug routes that creates the escape path.
Real-world attack patterns mirror known classes of issues such as those cataloged in the OWASP API Top 10 (e.g., Broken Object Level Authorization and Security Misconfiguration) and can be discovered by scanning for unauthenticated endpoints that return sensitive runtime information. Because bearer tokens are often passed in headers, an attacker may test for token reflection or host header poisoning within the container to see whether the token is validated against internal endpoints. If the container hosts multiple services and route segregation is weak, a single leaked token can facilitate movement across service boundaries, effectively breaking the container isolation.
Additionally, if the container runs with elevated privileges or mounts sensitive paths (like /var/run/secrets), a compromised token that leads to SSRF or command injection within the container can expose host-level resources. The scanner’s checks for SSRF, Server Side Request Forgery, and Unsafe Consumption are particularly relevant here, as they can identify endpoints that accept URLs or tokens and forward them without validation, enabling container escape via the token handling path.
Because middleBrick scans the unauthenticated attack surface and tests authentication mechanisms, it can detect exposed introspection endpoints and improper token usage patterns that facilitate container escape in Phoenix deployments. The scan includes checks for Data Exposure and SSRF that are directly applicable to this scenario.
Bearer Tokens-Specific Remediation in Phoenix — concrete code fixes
Remediation focuses on ensuring bearer tokens are validated securely, never reflected or proxied to internal endpoints, and that token handling code does not introduce SSRF or path traversal. Below are concrete examples for Phoenix (Elixir) applications using the Plug and Phoenix libraries.
Secure token validation without reflection
Do not echo the token in responses or logs. Validate the token against a secure store and ensure it is only used for authorization, not for routing or introspection.
defmodule MyApp.Auth do
import Plug.Conn
@bearer_prefix "Bearer "
def init(opts), do: opts
def call(conn, _opts) do
with [token] <- get_token(conn),
{:ok, claims} <- verify_token(token) do
# Attach claims for downstream use, do not send token back
put_private(conn, :current_user, claims)
else
_ -> send_resp(conn, 401, "Unauthorized")
end
end
defp get_token(conn) do
case get_req_header(conn, "authorization") do
[auth] when auth =~ @bearer_prefix ->
[_, token] = String.split(auth, " ", parts: 2)
{:ok, token}
_ ->
{:error, :missing}
end
end
defp verify_token(token) do
# Replace with your JWT library, e.g., Joken, Guardian, Pow
case MyApp.Jwt.verify(token) do
{:ok, claims} -> {:ok, claims}
{:error, _} -> {:error, :invalid}
end
end
end
Avoid SSRF via user-supplied URLs when using bearer tokens
Never forward user-provided URLs or tokens to arbitrary destinations. If your API makes outbound HTTP calls, validate and restrict destinations to prevent container escape via SSRF.
defmodule MyApp.HttpClient do
@allowed_hosts ["api.example.com", "internal.service.local"]
def get(url, token) when is_binary(url) do
uri = URI.parse(url)
if uri.host in @allowed_hosts do
headers = [{"authorization", "Bearer #{token}"}]
# Use your HTTP client, e.g., Finch or HTTPoison
Finch.build(:get, url, headers)
|> Finch.request(MyApp.FinchPool)
else
{:error, :forbidden_host}
end
end
end
Harden CORS and route segregation
Ensure CORS does not allow arbitrary origins when bearer tokens are in use, and avoid routing tokens to debug or introspection endpoints that may be exposed inside the container.
defmodule MyApp.Cors do
import Plug.Conn
def init(opts), do: opts
def call(conn, _opts) do
origin = get_req_header(conn, "origin")
if Enum.member?(["https://app.example.com"], List.first(origin)) do
conn
|> put_resp_header("access-control-allow-origin", List.first(origin))
|> put_resp_header("access-control-allow-credentials", "true")
else
conn
end
end
end
Ensure tokens are not logged or exposed via introspection
Disable any built-in introspection or debug routes in production, or protect them with strict network policies. Never include bearer tokens in logs or error messages that could be read from within the container.
# Configure your logger to exclude authorization headers
config :logger, :console,
format: "[$level] $message\n",
metadata: [:request_id]
# In your endpoint, avoid inspecting token in error reports
By combining these practices—strict token validation, no token reflection, SSRF controls, and hardened CORS—you reduce the risk that bearer tokens contribute to a container escape in Phoenix deployments. middleBrick’s scans can help identify exposed endpoints and improper token handling that could otherwise lead to escape scenarios.