CVE-2026-48597
Description
Allocation of Resources Without Limits or Throttling vulnerability in elixir-tesla tesla allows denial of service via atom table exhaustion in Tesla.Adapter.Mint.
Tesla.Adapter.Mint.open_conn/2 converts the URL scheme of every outgoing request to a BEAM atom via String.to_atom(uri.scheme) with no allow-list validation. BEAM atoms are never garbage-collected and the atom table is bounded (approximately 1,048,576 entries by default). An attacker who can influence the URL of a Tesla request — either via an application-level URL-forwarding feature (webhook, proxy, importer) or via a Location header returned by a server when Tesla.Middleware.FollowRedirects is in the pipeline — can mint one fresh permanent atom per request by varying the scheme string. After enough requests the atom table fills and the VM crashes, taking down the entire application.
This issue affects tesla: from 1.3.0 before 1.18.3.
Affected products
1- Range: from 1.3.0 before 1.18.3
Patches
14699c3cb3e2fMerge commit from fork
2 files changed · +34 −15
lib/tesla/adapter/mint.ex+21 −15 modified@@ -150,26 +150,32 @@ if Code.ensure_loaded?(Mint.HTTP) do end defp open_conn(uri, opts) do - opts = - with "https" <- uri.scheme, - global_cacertfile when not is_nil(global_cacertfile) <- - Application.get_env(:tesla, Tesla.Adapter.Mint)[:cacert] do - Map.update(opts, :transport_opts, [cacertfile: global_cacertfile], fn tr_opts -> - Keyword.put_new(tr_opts, :cacertfile, global_cacertfile) - end) - else - _ -> opts - end + with {:ok, scheme} <- parse_scheme(uri.scheme) do + opts = + with :https <- scheme, + global_cacertfile when not is_nil(global_cacertfile) <- + Application.get_env(:tesla, Tesla.Adapter.Mint)[:cacert] do + Map.update(opts, :transport_opts, [cacertfile: global_cacertfile], fn tr_opts -> + Keyword.put_new(tr_opts, :cacertfile, global_cacertfile) + end) + else + _ -> opts + end - opts = Map.put_new(opts, :mode, :passive) + opts = Map.put_new(opts, :mode, :passive) - with {:ok, conn} <- - HTTP.connect(String.to_atom(uri.scheme), uri.host, uri.port, Enum.into(opts, [])) do - # If there were redirects, and passed `closed_conn: false`, we need to close opened connections to these intermediate hosts. - {:ok, conn, Map.put(opts, :close_conn, true)} + with {:ok, conn} <- + HTTP.connect(scheme, uri.host, uri.port, Enum.into(opts, [])) do + # If there were redirects, and passed `closed_conn: false`, we need to close opened connections to these intermediate hosts. + {:ok, conn, Map.put(opts, :close_conn, true)} + end end end + defp parse_scheme("http"), do: {:ok, :http} + defp parse_scheme("https"), do: {:ok, :https} + defp parse_scheme(_), do: {:error, :unsupported_scheme} + defp make_request(conn, method, path, headers, body) when is_function(body) do with {:ok, conn, ref} <- HTTP.request(
test/tesla/adapter/mint_test.exs+13 −0 modified@@ -63,6 +63,19 @@ defmodule Tesla.Adapter.MintTest do assert conn.state == :closed end + test "unsupported scheme does not mint atoms" do + request = %Env{ + method: :get, + url: "atk-#{:erlang.unique_integer([:positive])}://127.0.0.1/" + } + + before_count = :erlang.system_info(:atom_count) + assert {:error, :unsupported_scheme} = call(request) + after_count = :erlang.system_info(:atom_count) + + assert after_count == before_count + end + test "certificates_verification" do request = %Env{ method: :get,
Vulnerability mechanics
Root cause
"The Tesla adapter for Mint improperly converts untrusted URL schemes into BEAM atoms without validation, leading to atom table exhaustion."
Attack vector
An attacker can trigger this vulnerability by influencing the URL scheme of a request processed by Tesla.Adapter.Mint.open_conn/2. This can be achieved through application-level features like URL forwarding or webhooks, or by exploiting the Tesla.Middleware.FollowRedirects middleware with a server that returns a Location header containing a novel scheme. Each such request creates a new, permanent atom in the BEAM VM's atom table. [ref_id=1]
Affected code
The vulnerability resides in the `open_conn/2` function within `lib/tesla/adapter/mint.ex`. Specifically, the line `HTTP.connect(String.to_atom(uri.scheme), ...)` is responsible for converting the URI scheme directly into an atom without prior validation. The patch modifies this section by introducing `parse_scheme/1` and using its output for the `HTTP.connect` call. [patch_id=4524231]
What the fix does
The patch introduces a new private function `parse_scheme/1` which validates the URL scheme against a hardcoded allow-list of supported schemes (http and https). Only recognized schemes are passed to `HTTP.connect/4` as atoms; any other scheme results in an `{:error, :unsupported_scheme}` tuple, preventing the creation of new atoms in the atom table. This directly addresses the vulnerability by ensuring that only valid schemes can be converted to atoms, thus preventing exhaustion. [patch_id=4524231]
Preconditions
- configThe application must use Tesla.Adapter.Mint. [ref_id=1]
- inputThe application must expose a feature that allows untrusted input to influence request URLs, or use Tesla.Middleware.FollowRedirects. [ref_id=1]
Reproduction
Stand up any application that accepts a user-supplied URL and forwards it through Tesla.Adapter.Mint. Send requests to the application, each with a distinct, previously unseen URL scheme (e.g. atk1://, atk2://, ...). Each request interns one new permanent atom; Mint rejects the connection but the atom persists. After approximately 1,000,000 requests the BEAM atom table is exhausted and the VM crashes. [ref_id=1]
Generated on Jun 2, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.