SpoonWood

SpoonWood

LiveView Websocket Security

Hello Everyone,

We are using LiveView to build a feature that displays some information in the admin dashboard of our Application, but we are not quite sure how to secure the websocket against access of non registered users.

Is the socket secure if we are using a signing salt and a Session key, having installed LiveView the exact Way thats recommended on Hexdocs.pm (we are using LiveView 0.8.1 currently)

Thank you very much in Advance

Most Liked

chrismccord

chrismccord

Creator of Phoenix

Add your live route definition behind your regular :admin plug/pipeline that performs admin user authentication and you are all set. You can reference the user off the HTTP request, and fallback to the user_id in the session, which comes from a signed token on the client, so you are covered in both HTTP and WebSocket cases security wise:

  
  # router
  scope "/admin", ... do
    pipe_through [:browser, :admin]
    
    live "/", MyLive
  end

  # LV
  defmodule MyLive do
    def mount(params, %{"admin_user_id" => id}, socket) do
      {:ok, assign_new(socket, :current_admin, fn -> Accounts.get_admin!(id) end)}
    end
  end
11
Post #3
josevalim

josevalim

Creator of Elixir

Here are the changes to enable this feature on top mix phx.gen.auth: Set the live_socket_id on login and disconnect on logout · dashbitco/mix_phx_gen_auth_demo@1eebcae · GitHub

It is really straight-forward and it is per session (i.e. it doesn’t disconnect all sessions, only the current one).

josevalim

josevalim

Creator of Elixir

Every operation you do against the database needs to be verified for user permission, you need to check if the user belongs to that organization, if they are the manager of a project, if they can access that chat room, etc. This logic is generally kept in the context, tied to the domain operation, so you go through it regardless if you are interacting with your domain via live views or controllers. In code, this means you should do:

Org.get_org_by_user(user, org_id)

Instead of:

Org.get_org(org_id)

Failing to scope this on regular HTTP requests can also be very troublesome, as it means a user can access any other organization.

The scenario you describe is only a concern if you are “preloading” permissions and storing it somewhere, which is not different from putting it in a cache, or an agent, live view state, etc.

And for things like user access, LV supports disconnecting any enabled socket. I even plan to submit changes to mix phx.gen.auth so we perform this disconnection by default on logout.

Last Post!

daveboo

daveboo

So, it would be unwise to have live routes behind this pipeline then?

scope “/”, MyAppWeb do
pipe_through [:browser, :visitor, :redirect_if_user_is_authenticated]

live "/user/register", UserNewLive

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

Other popular topics Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement