diff --git a/VERSION b/VERSION index 0516ac10..0041a435 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.65 +1.1.66 diff --git a/lib/supavisor/client_handler.ex b/lib/supavisor/client_handler.ex index 4c46f5fe..495f98c0 100644 --- a/lib/supavisor/client_handler.ex +++ b/lib/supavisor/client_handler.ex @@ -154,15 +154,11 @@ defmodule Supavisor.ClientHandler do Logger.debug("ClientHandler: Client startup message: #{inspect(hello)}") {type, {user, tenant_or_alias, db_name}} = HH.parse_user_info(hello.payload) - not_allowed = ["\"", "\\"] + # Validate user and db_name according to PostgreSQL rules. + # The rules are: 1-63 characters, alphanumeric, underscore and $ + rule = ~r/^[a-z_][a-z0-9_$]*$/ - if String.contains?(user, not_allowed) or String.contains?(db_name, not_allowed) do - reason = "Invalid characters in user or db_name" - Logger.error("ClientHandler: #{inspect(reason)}") - Telem.client_join(:fail, data.id) - HH.send_error(data.sock, "XX000", "Authentication error, reason: #{inspect(reason)}") - {:stop, {:shutdown, :invalid_characters}} - else + if user =~ rule and db_name =~ rule do log_level = case hello.payload["options"]["log_level"] do nil -> nil @@ -173,6 +169,12 @@ defmodule Supavisor.ClientHandler do {:keep_state, %{data | log_level: log_level}, {:next_event, :internal, {:hello, {type, {user, tenant_or_alias, db_name}}}}} + else + reason = "Invalid format for user or db_name" + Logger.error("ClientHandler: #{inspect(reason)}") + Telem.client_join(:fail, tenant_or_alias) + HH.send_error(data.sock, "XX000", "Authentication error, reason: #{inspect(reason)}") + {:stop, {:shutdown, :invalid_format}} end {:error, error} -> diff --git a/test/integration/proxy_test.exs b/test/integration/proxy_test.exs index 689912f8..168146ba 100644 --- a/test/integration/proxy_test.exs +++ b/test/integration/proxy_test.exs @@ -249,12 +249,12 @@ defmodule Supavisor.Integration.ProxyTest do assert [%Postgrex.Result{rows: [["1"]]}] = P.SimpleConnection.call(pid, {:query, "select 1;"}) end - test "invalid characters in user or db_name" do + test "invalid format for user or db_name" do Process.flag(:trap_exit, true) db_conf = Application.get_env(:supavisor, Repo) url = - "postgresql://user\"user.#{@tenant}:#{db_conf[:password]}@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/postgres\\\\\\\\\"\\" + "postgresql://user\"user.#{@tenant}:#{db_conf[:password]}@#{db_conf[:hostname]}:#{Application.get_env(:supavisor, :proxy_port_transaction)}/post gres\\\\\\\\\"\\" assert {:error, {_, @@ -262,8 +262,7 @@ defmodule Supavisor.Integration.ProxyTest do %Postgrex.Error{ postgres: %{ code: :internal_error, - message: - "Authentication error, reason: \"Invalid characters in user or db_name\"", + message: "Authentication error, reason: \"Invalid format for user or db_name\"", pg_code: "XX000", severity: "FATAL", unknown: "FATAL"