Api Rate Abuse in Phoenix with Saml
Api Rate Abuse in Phoenix with Saml — how this specific combination creates or exposes the vulnerability
Rate abuse in a Phoenix application that uses SAML for authentication can occur when rate-limiting is applied after the SAML assertion has been validated, or when the identity provider (IdP) or service provider (SP) endpoints are not individually protected. Without per-consumer or per-identity limits, an attacker who obtains or guesses a valid SAML endpoint can flood the route with login requests, triggering issues such as session exhaustion, elevated CPU usage due to signature verification, or bypass of throttling via rapid token requests.
Phoenix pipelines typically decode and validate SAML assertions in a pluggable authentication layer. If rate limiting is implemented at the Phoenix router level only for the unprotected session creation route, an attacker can repeatedly POST SAML responses to that route. Each request triggers XML parsing and cryptographic verification, which are CPU-intensive operations. This can lead to denial of service for legitimate users and may amplify the impact of other attacks, such as brute-forcing NameID values or replaying captured assertions.
Because SAML often carries user identity in the NameID element, rate abuse can also be targeted at identity-specific endpoints. For example, an endpoint that accepts a SAML response and maps the NameID to a local account may be called repeatedly with different assertions, causing the system to perform repeated lookups and potentially exposing information through timing differences or error messages. MiddleBrick’s checks for Rate Limiting and Authentication help surface these gaps by testing unauthenticated endpoints and evaluating whether limits apply at the identity or session level.
In practice, a misconfigured pipeline might validate the SAML signature but fail to enforce request caps on the /sso/consume route. MiddleBrick’s scans detect missing rate limits and weak throttling strategies, providing prioritized findings with severity and remediation guidance. This is especially important when continuous monitoring is enabled via the Pro plan, where APIs are scanned on a configurable schedule and alerts notify you when a risk score drops.
When integrating third-party identity providers, ensure that both the SP and IdP endpoints are covered by rate-limiting strategies. MiddleBrick’s OpenAPI/Swagger spec analysis can cross-reference spec definitions with runtime findings, highlighting routes that accept SAML bindings without corresponding protections. By combining specification-aware scanning with active checks, you can identify whether rate limits are applied before or after authentication and whether they vary by identity or client.
Saml-Specific Remediation in Phoenix — concrete code fixes
To mitigate rate abuse in Phoenix with SAML, apply rate limiting close to the authentication endpoint and scope limits by identity where possible. Below are concrete code examples showing how to protect the SAML consumer route using Plug-based rate limiting and how to structure SAML responses securely.
First, add a rate-limiting plug before your SAML consumer in the pipeline. This example uses hammer to track requests per identity extracted from the SAML assertion. Place this plug before the route that processes the SAML response:
defmodule MyAppWeb.Plugs.RateLimitSaml do
@max_requests 5
@period 60_000
def init(opts), do: opts
def call(conn, _opts) do
# Extract NameID from SAML assertion in the request body or params
nameid = extract_nameid_from_saml(conn)
case Hammer.check_rate({"saml_login", nameid}, @period, @max_requests) do
{:allow, _} -> conn
{:deny, _} ->
conn
|> Plug.Conn.put_status(429)
|> Phoenix.Controller.json(%{error: "rate limit exceeded"})
|> Plug.Conn.halt()
end
end
defp extract_nameid_from_saml(conn) do
# Simplified extraction; in practice parse the SAMLResponse parameter
case conn.params["SAMLResponse"] do
nil -> "unknown"
saml ->
# Decode and parse the assertion to obtain NameID
# Use a library like saml_sp or xml_simple to extract the value
"nameid_placeholder"
end
end
end
Then plug this into your router before the SAML consumer route:
pipeline :api do
plug MyAppWeb.Plugs.RateLimitSaml
# other plugs such as :fetch_session, :protect_from_forgery
end
scope "/sso", MyAppWeb do
pipe_through :api
post "/consume", SamlConsumerController, :consume
end
Second, ensure your SAML response signing and encryption settings follow security best practices. In your SAML configuration, prefer signed assertions and require NameID format consistency:
config :saml_sp, SAML.SettingsProvider,
idp_cert_path: <%= System.fetch_env!("IDP_CERT_PATH") >,
sp_key_path: <%= System.fetch_env!("SP_KEY_PATH") >,
sp_cert_path: <%= System.fetch_env!("SP_CERT_PATH") >,
name_id_format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
want_assertions_signed: true,
want_name_id_signed: false
Third, apply global rate limits at the Phoenix router for the SAML endpoint regardless of identity, as a safety net:
scope "/sso", MyAppWeb do
plug Plug.RateLimiter, max: 10, period: 60
post "/consume", SamlConsumerController, :consume
end
These steps align with MiddleBrick’s findings for Rate Limiting and Authentication, and can be validated using the CLI with middlebrick scan <url> or through the Web Dashboard to track improvements over time. The Pro plan enables continuous monitoring so that any regression in rate-limiting coverage is caught early via Slack/Teams alerts.