Phoenix live view security

I am wondering if live view endpoint (/live usually) can be used without a live_render (or a live route).

For example, let’s say I have this live view:

defmodule SecretLiveView do
  use Phoenix.LiveView

  def render(assigns) do
    SecretView.render("secret.html", assigns)
  end

  def mount(_session, socket) do
    # are we sure this cannot be called without a live_render ?

    {:ok, assign(socket, secret: SecretData.get_all())}
  end
end

And the following controller:

defmodule SecretController do
  use SecretApp.Web, :controller

  plug(:ensure_security)

  def index(conn, _params) do
    live_render(conn, SecretLiveView,
      session: %{user_id: get_session(conn, :user_id)}
    )
  end
end

SecretController has the ensure_security plug, which makes it secure, but SecretLiveView is “unprotected”. Is this scenario OK? Or can the SecretLiveView be mounted directly from the /live socket?

Do I need to add something like this (even if I don’t need the user id in my live view):

defmodule SecretLiveView do
  use Phoenix.LiveView

  def render(assigns) do
    SecretView.render("secret.html", assigns)
  end

  def mount(%{user_id: id}, socket) when not is_nil(id) do
    {:ok, assign(socket, secret: SecretData.get_all())}
  end

  def mount(_session, _socket) do
    {:error, :unauthorized}
  end
end
3 Likes

LV sessions are signed into a token and passed up by the client, so the only way your mount/2 is called is with a verified session, otherwise it fails and aborts the operation. So you don’t need the :unauthorized clause since every live_render has a signed session.

5 Likes

This is what I thought, but as it would introduce a big security vulnerability if it wasn’t the case I wanted to be sure.

Thank you

1 Like