From 9a2a2cc744866d0729db9abd1aae6d3d5c8c9b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 28 Oct 2026 11:44:55 +0100 Subject: [PATCH] Bind port limits during URI.parse (CVE-2026-109821) --- lib/elixir/lib/uri.ex | 21 +++++++++++++++++++-- lib/elixir/test/elixir/uri_test.exs | 8 ++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/elixir/lib/uri.ex b/lib/elixir/lib/uri.ex index 3c6433c05..d25a9c995 100644 --- a/lib/elixir/lib/uri.ex +++ b/lib/elixir/lib/uri.ex @@ -813,7 +813,24 @@ def parse(string) when is_binary(string) do {authority, userinfo, host, port} = split_authority(authority_with_slashes) scheme = scheme && String.downcase(scheme) - port = port || (scheme && default_port(scheme)) + + # Leading zeros are removed and then ports with more than + # 6 digits or outside of the valid range are discarded + port = + case port && String.trim_leading(port, "0") do + nil -> + scheme && default_port(scheme) + + "" -> + 0 + + port when byte_size(port) <= 6 -> + port = String.to_integer(port) + if port in 0..65535, do: port + + _ -> + nil + end %URI{ scheme: scheme, @@ -849,7 +866,7 @@ defp split_authority("//" <> authority) do destructure [_, _, userinfo, host, _, port], components userinfo = nilify(userinfo) host = if nilify(host), do: host |> String.trim_leading("[") |> String.trim_trailing("]") - port = if nilify(port), do: String.to_integer(port) + port = nilify(port) {authority, userinfo, host, port} end diff --git a/lib/elixir/test/elixir/uri_test.exs b/lib/elixir/test/elixir/uri_test.exs index 8772ec97d..7b5bf59ce 100644 --- a/lib/elixir/test/elixir/uri_test.exs +++ b/lib/elixir/test/elixir/uri_test.exs @@ -781,6 +781,14 @@ test "splits authority" do } assert URI.parse("http://foo.com:4444") == expected_uri + + assert URI.parse("http://foo.com:65535").port == 65535 + assert URI.parse("http://foo.com:065535").port == 65535 + assert URI.parse("http://foo.com:65536").port == nil + assert URI.parse("http://foo.com:0000000065535").port == 65535 + assert URI.parse("http://foo.com:0000000065536").port == nil + assert URI.parse("http://foo.com:0000000000").port == 0 + assert URI.parse("http://foo.com:#{String.duplicate("9", 1000)}").port == nil end test "can parse bad URIs" do -- 2.52.0