HIGH bleichenbacher attackphoenixmutual tls

Bleichenbacher Attack in Phoenix with Mutual Tls

Bleichenbacher Attack in Phoenix with Mutual Tls

A Bleichenbacher attack targets RSA-based padding schemes (for example PKCS#1 v1.5) by sending many carefully crafted ciphertexts and observing server behavior or timing differences to decrypt data or recover the private key. When this attack scenario is considered in a Phoenix application that uses Mutual TLS (mTLS), the combination of an mTLS-authenticated channel and an RSA-based key exchange or token format can expose subtle vulnerabilities if padding validation is not constant-time and strictly enforced.

In a typical setup, the client presents a client certificate during the TLS handshake, and the server may also expect an encrypted or signed token (for example an RSA-encrypted session key or an RSA-signed JWT) carrying claims or a session identifier. If the server decrypts or verifies this RSA-encrypted/signed payload using a non-constant-time padding check, an attacker can perform a Bleichenbacher-style adaptive chosen-ciphertext attack even though the transport is protected by mTLS. The mTLS layer ensures client authentication and integrity at the transport level, but it does not inherently prevent application-layer padding oracles. In fact, mTLS may increase the value of the target (strong client identity plus application data), motivating more precise probing of the application component.

Consider a Phoenix endpoint that accepts an encrypted_session parameter containing an RSA-encrypted blob. The server decrypts it with :public_key.decrypt/2 and uses the result to look up a session. If error responses differ based on padding validity (e.g., returning a 400 versus a 401, or leaking timing differences), an attacker can iteratively decrypt ciphertexts without having the private key. This becomes a practical risk when the RSA operation is used for authentication tokens or API keys rather than simple transport encryption. The attack surface is not theoretical: similar issues have been observed in protocols and libraries where PKCS#1 v1.5 padding is used and error handling or timing leaks are not carefully controlled.

To detect this with middleBrick, you can submit the Phoenix API endpoint for an unauthenticated scan. The tool runs checks including Input Validation, Authentication, and Property Authorization in parallel, and it references real OWASP API Top 10 categories and findings. If your API exposes an RSA-based operation with distinguishable error responses, middleBrick can highlight the risk and provide remediation guidance. Note that middleBrick reports findings and provides guidance; it does not fix, patch, or block the application.

Mutual Tls-Specific Remediation in Phoenix

Remediation centers on ensuring that RSA decryption and verification operations use constant-time padding checks and that error handling does not leak distinguishing information. In Phoenix, this typically means wrapping cryptographic operations so that timing and error paths are uniform, and avoiding branching on padding validity.

Example: RSA decryption with constant-time behavior using :public_key.decrypt/2 and explicit error mapping. Instead of allowing the library to raise or return distinct errors for padding failures, catch all decryption outcomes and return a uniform response.

defmodule MyApp.Session do
  @moduledoc """
  Secure session decryption with constant-time style handling.
  """

  @spec decrypt_session(binary) :: {:ok, map()} | {:error, :invalid}
  def decrypt_session(encrypted_blob) when is_binary(encrypted_blob) do
    case :public_key.decrypt(encrypted_blob, [:rsa_pkcs1, :deterministic]) do
      {:ok, plaintext} ->
        # Validate structure, then return session data
        case validate_session_payload(plaintext) do
          {:ok, session} -> {:ok, session}
          {:error, _} -> {:error, :invalid}
        end

      # Map low-level errors to a uniform invalid response to avoid padding oracles
      {:error, _reason} ->
        {:error, :invalid}
    end
  end

  defp validate_session_payload(plaintext) do
    # Perform strict validation; do not leak which step failed
    with {:ok, %{session_id: id, expiry: expiry}} <- parse_payload(plaintext),
         true <- session_valid?(id, expiry) do
      {:ok, %{session_id: id, expiry: expiry}}
    else
      _ -> {:error, :invalid}
    end
  end
end

Example: JWT verification with an RSA public key, using a library that supports constant-time verification or ensuring uniform error handling. Configure the Phoenix endpoint to treat verification failures uniformly.

defmodule MyApi.Auth do
  @moduledoc """
  Verify RSA-signed tokens with uniform error handling.
  """

  @spec verify_token(binary, map()) :: {:ok, map()} | {:error, :invalid}
  def verify_token(token, public_key) when is_binary(token) and is_map(public_key) do
    case MyJwt.verify(token, {:public_key, public_key}, algorithm: :RS256) do
      {:ok, claims} ->
        # Additional business checks, always returning the same error shape on failure
        if claims["exp"] && claims["exp"] > System.system_time(:second) do
          {:ok, claims}
        else
          {:error, :invalid}
        end

      # Do not distinguish between signature, padding, or format errors
      {:error, _} ->
        {:error, :invalid}
    end
  end
end

In addition to code-level fixes, review your API specification (OpenAPI/Swagger) for endpoints that accept RSA-encrypted or signed payloads. Use middleBrick’s OpenAPI/Swagger analysis (with full $ref resolution) to cross-reference spec definitions with runtime behavior. If you adopt the Pro plan, continuous monitoring can help detect regressions in error uniformity over time. For CI/CD enforcement, the GitHub Action can fail builds if security scores drop below your chosen threshold.

Frequently Asked Questions

Does mTLS prevent a Bleichenbacher attack?
No. Mutual TLS secures the transport and provides client authentication, but it does not prevent application-layer padding oracles. If your Phoenix app uses RSA decryption or signing with non-constant-time validation, an attacker can still perform a Bleichenbacher attack at the application layer.
How can I detect padding oracle risks in my Phoenix API?
Submit your endpoint to middleBrick for an unauthenticated scan. It runs parallel checks including Input Validation and Authentication and maps findings to frameworks like OWASP API Top 10. The report highlights risks and provides remediation guidance without exposing internal architecture.