From 9639617066779cee19fde76b5c718c2540ac6bba Mon Sep 17 00:00:00 2001 From: Peaceful James <66864163+peaceful-james@users.noreply.github.com> Date: Thu, 11 Jul 2024 02:04:44 +0100 Subject: [PATCH] Avoid fixation attacks by renewing session ID (#72) * Use `residentKey` instead of `requireResidentKey` * typo * provide requireResidentKey as well, just in case * Set require true only when r.key == required * Avoid fixation attacks by renewing session ID * delete CSRF token when renewing session --------- Co-authored-by: Owen Bickford --- templates/controllers/session.ex | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/templates/controllers/session.ex b/templates/controllers/session.ex index a6cfd12a..97220c88 100644 --- a/templates/controllers/session.ex +++ b/templates/controllers/session.ex @@ -15,7 +15,7 @@ defmodule <%= inspect @web_pascal_case %>.Session do else _error -> conn - |> clear_session() + |> renew_session() end end @@ -32,7 +32,7 @@ defmodule <%= inspect @web_pascal_case %>.Session do {:error, _} -> conn - |> clear_session() + |> renew_session() |> put_flash(:error, "Please sign in.") |> redirect(to: ~p"/sign-in") end @@ -44,8 +44,31 @@ defmodule <%= inspect @web_pascal_case %>.Session do |> Identity.delete_all_user_sessions() conn - |> clear_session() + |> renew_session() |> put_flash(:info, "Successfully signed out.") |> redirect(to: ~p"/") end + + # This function renews the session ID and erases the whole + # session to avoid fixation attacks. If there is any data + # in the session you may want to preserve after log in/log out, + # you must explicitly fetch the session data before clearing + # and then immediately set it after clearing, for example: + # + # defp renew_session(conn) do + # preferred_locale = get_session(conn, :preferred_locale) + # + # conn + # |> configure_session(renew: true) + # |> clear_session() + # |> put_session(:preferred_locale, preferred_locale) + # end + # + defp renew_session(conn) do + delete_csrf_token() + + conn + |> configure_session(renew: true) + |> clear_session() + end end