HIGH unicode normalizationchiapi keys

Unicode Normalization in Chi with Api Keys

Unicode Normalization in Chi with Api Keys — how this specific combination creates or exposes the vulnerability

Chi is an Elixir web framework that uses pattern-based routing and parameter parsing. When API keys are passed in HTTP headers or query parameters, Chi developers often normalize route segments or controller parameters to avoid duplicate routes or injection-like issues. Unicode normalization can interact poorly with Api Keys when keys are compared after normalization transformations, or when keys are embedded in paths or headers that Chi routes and parses.

For example, an Api Key containing characters like é (U+00E9) might be normalized by an upstream proxy or client into its composed form é (U+0065 U+0301). If Chi normalizes incoming request paths or headers differently than the system that issued the key, the normalized key no longer matches the stored canonical key. This mismatch can cause authentication bypasses or forced key collisions, effectively weakening the intended secrecy of the Api Key.

In addition, if an API endpoint accepts an Api Key as a user-controlled parameter (for example, ?api_key=...) and then uses that key in internal logic or logs without canonical normalization, an attacker can supply multiple visually identical representations to probe for key comparisons, timing differences, or logging inconsistencies. These behaviors can be discovered by the 12 security checks in middleBrick, including Input Validation and Property Authorization, which flag inconsistencies between spec-defined parameter constraints and runtime behavior.

When OpenAPI specs are provided, middleBrick resolves $ref definitions and cross-references them against runtime findings. This helps identify whether Api Key definitions in the spec tolerate multiple Unicode representations that could lead to authentication bypass or information leakage across normalization boundaries. The scanner does not modify code, but highlights how normalization inconsistencies may expose keys through authentication, authorization, or introspection endpoints.

Api Keys-Specific Remediation in Chi — concrete code fixes

To reduce risk, normalize Api Keys consistently in Chi before storage, comparison, and logging. Use a deterministic normalization strategy and apply it uniformly across issuance, validation, and introspection.

Example: Canonical normalization before comparison

defmodule MyApp.ApiKey do
  @moduledoc """
  Handles Api Key normalization and comparison.
  """

  @doc """
  Normalize an Api Key by NFC and downcasing ASCII letters.
  """
  def normalize(key) when is_binary(key) do
    key
    |> String.downcase()
    |> :unicode.characters_to_binary(:nfc)
  end

  @doc """
  Validate and compare keys in constant time.
  """
  def valid_key?(input, stored_key) do
    input
    |> normalize()
    |> MyApp.Crypto.secure_compare(stored_key)
  end
end

Example: Using the normalized key in a Plug pipeline

defmodule MyApp.ApiKeyPlug do
  import Plug.Conn

  def init(opts), do: opts

  def call(conn, _opts) do
    case conn.query_params["api_key"] || get_req_header(conn, "x-api-key") do
      [raw_key] ->
        normalized = MyApp.ApiKey.normalize(raw_key)
        # Perform lookup using the normalized key
        case MyApp.Repo.get_by(MyApp.ApiKey, key_hash: hash_key(normalized)) do
          nil -> send_resp(conn, 401, "Unauthorized")
          key_record -> assign(conn, :api_key, key_record)
        end
      _ ->
        send_resp(conn, 400, "Missing api_key")
    end
  end

  defp hash_key(key) do
    :crypto.hash(:sha256, key)
  end
end

Example: Issuing keys with normalization at creation

defmodule MyApp.KeyGenerator do
  @doc """
  Generate and normalize an Api Key before persisting.
  """
  def generate_key() do
    raw_key = MyApp.Crypto.secure_random_hex(32)
    normalized = MyApp.ApiKey.normalize(raw_key)
    # Store only the normalized version or its hash
    %MyApp.ApiKey{key_hash: hash_key(normalized)}
  end

  defp hash_key(key) do
    :crypto.hash(:sha256, key)
  end
end

For broader coverage, including detection of inconsistencies between spec definitions and runtime behavior, you can run a scan with middleBrick. Use the CLI to validate your endpoints: middlebrick scan https://api.example.com/openapi.json. The dashboard and reports can help track how parameter handling and authentication patterns evolve over time. The Pro plan adds continuous monitoring and CI/CD integration to flag regressions before deployment, while the MCP Server enables scanning directly from AI coding assistants in your workflow.

Frequently Asked Questions

Why does Unicode normalization affect Api Key security in Chi applications?
Chi routes and parameter parsing can interact with Api Keys that traverse proxies or clients that apply different Unicode normalization forms. If keys are compared after normalization in different layers, visually identical keys may fail to match, leading to authentication bypasses or collisions.
Can middleBrick detect normalization-related issues for Api Keys in Chi APIs?
Yes. middleBrick runs Input Validation and Property Authorization checks that compare spec definitions (including parameter encoding rules) with runtime behavior. When an OpenAPI spec is provided, it resolves $ref definitions and highlights mismatches that could expose keys through normalization inconsistencies.