VYPR
Low severityNVD Advisory· Published Jun 17, 2025· Updated Apr 15, 2026

CVE-2025-4754

CVE-2025-4754

Description

Insufficient Session Expiration vulnerability in ash-project ash_authentication_phoenix allows Session Hijacking. This vulnerability is associated with program files lib/ash_authentication_phoenix/controller.ex.

This issue affects ash_authentication_phoenix until 2.10.0.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
ash_authentication_phoenixHex
< 2.10.02.10.0

Patches

1
a3253fb4fc71

improvement: revoke stored sessions on log out (#634)

10 files changed · +57 21
  • dev/dev_web/controllers/auth_controller.ex+1 1 modified
    @@ -26,7 +26,7 @@ defmodule DevWeb.AuthController do
       @impl true
       def sign_out(conn, _params) do
         conn
    -    |> clear_session()
    +    |> clear_session(:ash_authentication_phoenix)
         |> render("sign_out.html")
       end
     end
    
  • documentation/tutorials/get-started.md+1 1 modified
    @@ -116,7 +116,7 @@ defmodule ExampleWeb.AuthController do
         return_to = get_session(conn, :return_to) || ~p"/"
     
         conn
    -    |> clear_session()
    +    |> clear_session(:my_app)
         |> redirect(to: return_to)
       end
     end
    
  • lib/ash_authentication_phoenix/controller.ex+32 11 modified
    @@ -77,6 +77,7 @@ defmodule AshAuthentication.Phoenix.Controller do
       """
     
       alias AshAuthentication.Plug.Dispatcher
    +  alias AshAuthentication.Plug.Helpers
       alias Plug.Conn
     
       @type t :: module
    @@ -107,7 +108,7 @@ defmodule AshAuthentication.Phoenix.Controller do
           @behaviour AshAuthentication.Phoenix.Controller
           @behaviour AshAuthentication.Plug
           import Phoenix.Controller
    -      import Plug.Conn
    +      import Plug.Conn, except: [clear_session: 1]
           import AshAuthentication.Phoenix.Plug
           import AshAuthentication.Phoenix.Controller
     
    @@ -137,15 +138,6 @@ defmodule AshAuthentication.Phoenix.Controller do
             |> render("failure.html")
           end
     
    -      @doc false
    -      @impl true
    -      @spec sign_out(Conn.t(), map) :: Conn.t()
    -      def sign_out(conn, _params) do
    -        conn
    -        |> clear_session()
    -        |> render("sign_out.html")
    -      end
    -
           @doc false
           @impl true
           @spec call(Conn.t(), any) :: Conn.t()
    @@ -203,7 +195,36 @@ defmodule AshAuthentication.Phoenix.Controller do
             end
           end
     
    -      defoverridable success: 4, failure: 3, sign_out: 2
    +      defoverridable success: 4, failure: 3
         end
       end
    +
    +  defmacro clear_session(_conn) do
    +    raise """
    +    Using clear_session/1 in your `auth_controller` is deprecated. Please use `clear_session/2` instead,
    +    passing the conn and the otp_app.
    +
    +    For example:
    +
    +        conn
    +        |> clear_session(conn, :my_app)
    +
    +
    +    This ensures that session tokens & bearer tokens are revoked on logout.
    +
    +    If you wish to retain the old behavior (not advised), call `Plug.Conn.clear_session/1` directly.
    +    """
    +  end
    +
    +  @doc """
    +  Clears the session and revokes bearer and session tokens.
    +
    +  This ensures that session tokens & bearer tokens are revoked on logout.
    +  """
    +  def clear_session(conn, otp_app) do
    +    conn
    +    |> Helpers.revoke_bearer_tokens(otp_app)
    +    |> Helpers.revoke_session_tokens(otp_app)
    +    |> Plug.Conn.clear_session()
    +  end
     end
    
  • lib/ash_authentication_phoenix/plug.ex+12 0 modified
    @@ -49,6 +49,18 @@ defmodule AshAuthentication.Phoenix.Plug do
         Helpers.revoke_bearer_tokens(conn, otp_app)
       end
     
    +  @doc """
    +  Revoke all token(s) in the session.
    +
    +  A wrapper around `AshAuthentication.Plug.Helpers.revoke_session_tokens/2` with
    +  the `otp_app` as extracted from the endpoint.
    +  """
    +  @spec revoke_session_tokens(Conn.t(), any) :: Conn.t()
    +  def revoke_session_tokens(conn, _opts) do
    +    otp_app = conn.private.phoenix_endpoint.config(:otp_app)
    +    Helpers.revoke_session_tokens(conn, otp_app)
    +  end
    +
       @doc """
       Store the actor in the connections' session.
       """
    
  • lib/mix/tasks/ash_authentication_phoenix.install.ex+4 3 modified
    @@ -98,14 +98,15 @@ if Code.ensure_loaded?(Igniter) do
           if router do
             web_module = Igniter.Libs.Phoenix.web_module(igniter)
             overrides = Igniter.Libs.Phoenix.web_module_name(igniter, "AuthOverrides")
    +        otp_app = Igniter.Project.Application.app_name(igniter)
     
             igniter
             |> Igniter.Project.Formatter.import_dep(:ash_authentication_phoenix)
             |> Igniter.compose_task("igniter.add_extension", ["phoenix"])
             |> setup_routes_alias()
             |> warn_on_missing_modules(options, argv, install?)
             |> do_or_explain_tailwind_changes()
    -        |> create_auth_controller()
    +        |> create_auth_controller(otp_app)
             |> create_overrides_module(overrides)
             |> add_auth_routes(overrides, options, router, web_module)
             |> create_live_user_auth(web_module)
    @@ -318,7 +319,7 @@ if Code.ensure_loaded?(Igniter) do
           )
         end
     
    -    defp create_auth_controller(igniter) do
    +    defp create_auth_controller(igniter, otp_app) do
           Igniter.Project.Module.create_module(
             igniter,
             Igniter.Libs.Phoenix.web_module_name(igniter, "AuthController"),
    @@ -372,7 +373,7 @@ if Code.ensure_loaded?(Igniter) do
               return_to = get_session(conn, :return_to) || ~p"/"
     
               conn
    -          |> clear_session()
    +          |> clear_session(:#{otp_app})
               |> put_flash(:info, "You are now signed out")
               |> redirect(to: return_to)
             end
    
  • mix.exs+1 1 modified
    @@ -118,7 +118,7 @@ defmodule AshAuthentication.Phoenix.MixProject do
       # Run "mix help deps" to learn about dependencies.
       defp deps do
         [
    -      {:ash_authentication, "~> 4.8"},
    +      {:ash_authentication, "~> 4.9 and >= 4.9.1"},
           {:ash_phoenix, "~> 2.0"},
           {:ash, "~> 3.0"},
           {:jason, "~> 1.0"},
    
  • mix.lock+2 2 modified
    @@ -1,6 +1,6 @@
     %{
    -  "ash": {:hex, :ash, "3.5.19", "defd1c6b94475352a7b69f430b792fb64e3a9f7ca030195737bb97dc0f1311b5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ded976230b1ef823aeb25008cc62de6545bf3ad6208cf1f3badb598fa6c01375"},
    -  "ash_authentication": {:hex, :ash_authentication, "4.9.0", "0286b5df6e5006d16811b18f0efcd691fa7895a0a3aa1b091986a61da31a2a8a", [:mix], [{:argon2_elixir, "~> 4.0", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:ash, ">= 3.4.29 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:assent, "~> 0.2.13", [hex: :assent, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:finch, "~> 0.19", [hex: :finch, repo: "hexpm", optional: false]}, {:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.5", [hex: :joken, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}], "hexpm", "dde0c702b26e7354d81ea4a9bb334c27ce11a59876df8c5d4d5b0bebe4b7ad4e"},
    +  "ash": {:hex, :ash, "3.5.21", "389303c193962d67fd59da18a3557f5015fdfdaeddaa77150db539bc7203d1a1", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.6.4 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.11", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.65 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cb90005d1972e22d0d2ae514394e43e0d67cce18c4485595aa3d3e4bbf25260f"},
    +  "ash_authentication": {:hex, :ash_authentication, "4.9.1", "f5465abb973777ed7150c94f89902d0050d4debca1cf6ba8930e18e4de379a08", [:mix], [{:argon2_elixir, "~> 4.0", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:ash, ">= 3.4.29 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:ash_postgres, "~> 2.0", [hex: :ash_postgres, repo: "hexpm", optional: true]}, {:assent, "~> 0.2.13", [hex: :assent, repo: "hexpm", optional: false]}, {:bcrypt_elixir, "~> 3.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:finch, "~> 0.19", [hex: :finch, repo: "hexpm", optional: false]}, {:igniter, "~> 0.4", [hex: :igniter, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:joken, "~> 2.5", [hex: :joken, repo: "hexpm", optional: false]}, {:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}], "hexpm", "e5022a1d149c04fc529277a8174f0004b617d5530f080ce4e98a9452c5586970"},
       "ash_phoenix": {:hex, :ash_phoenix, "2.3.6", "c2bea1673af52f305b2fe0c04999bd1f0dc8e127d4757a3d7f42d0b9dea16a7a", [:mix], [{:ash, ">= 3.5.13 and < 4.0.0-0", [hex: :ash, repo: "hexpm", optional: false]}, {:igniter, "~> 0.6", [hex: :igniter, repo: "hexpm", optional: true]}, {:inertia, "~> 2.3", [hex: :inertia, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.6 or ~> 1.6", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20.3 or ~> 1.0-rc.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:spark, ">= 2.2.29 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}], "hexpm", "6923dca70fe1d533864134999f4d9c5c59ef745a6b50982d42d60c18966474cd"},
       "assent": {:hex, :assent, "0.2.13", "11226365d2d8661d23e9a2cf94d3255e81054ff9d88ac877f28bfdf38fa4ef31", [:mix], [{:certifi, ">= 0.0.0", [hex: :certifi, repo: "hexpm", optional: true]}, {:finch, "~> 0.15", [hex: :finch, repo: "hexpm", optional: true]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: true]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:req, "~> 0.4", [hex: :req, repo: "hexpm", optional: true]}, {:ssl_verify_fun, ">= 0.0.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: true]}], "hexpm", "bf9f351b01dd6bceea1d1f157f05438f6765ce606e6eb8d29296003d29bf6eab"},
       "bcrypt_elixir": {:hex, :bcrypt_elixir, "3.3.2", "d50091e3c9492d73e17fc1e1619a9b09d6a5ef99160eb4d736926fd475a16ca3", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "471be5151874ae7931911057d1467d908955f93554f7a6cd1b7d804cac8cef53"},
    
  • test/mix/tasks/ash_authentication_phoenix.install_test.exs+1 1 modified
    @@ -142,7 +142,7 @@ defmodule Mix.Tasks.AshAuthenticationPhoenix.InstallTest do
             return_to = get_session(conn, :return_to) || ~p"/"
     
             conn
    -        |> clear_session()
    +        |> clear_session(:test)
             |> put_flash(:info, "You are now signed out")
             |> redirect(to: return_to)
           end
    
  • test/support/accounts/user.ex+2 0 modified
    @@ -96,6 +96,8 @@ defmodule Example.Accounts.User do
       end
     
       authentication do
    +    session_identifier(:jti)
    +
         add_ons do
           confirmation :confirm do
             monitor_fields([:email])
    
  • test/support/auth_controller.ex+1 1 modified
    @@ -26,7 +26,7 @@ defmodule AshAuthentication.Phoenix.Test.AuthController do
       @impl true
       def sign_out(conn, _params) do
         conn
    -    |> clear_session()
    +    |> clear_session(:ash_authentication_phoenix)
         |> render(:signed_out)
       end
     end
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.