smon
Hi everyone!
I have a “working prototype”, but am not quite 100% sure if I missed some crucial security implications - so here I am asking again for your suggestions. ![]()
A little bit of context
Our Phoenix application reverse proxies a CouchDB (beside other things). Users (archaeologists) work in an Electron Desktop client that uses PouchDB and sync projects through the Phoenix endpoint. Each project resides in its own database within a single CouchDB instance.
What I want to to do
To get a feel of LiveView, my goal was to implement a monitoring view for a given project that checks for data inconsistencies and let’s us give feedback to our users. I am not 100% sure if my solution of handling the credentials is really save.
** Implementation so far **
In my endpoint.ex I set up the session options as follows:
@session_options [
(...)
signing_salt: "<value>",
encryption_salt: "<another value>"
]
socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
And I created my own authentication plug like this:
def api_auth(%{params: %{"project" => project}} = conn, _) do
with {name, password} <- Plug.BasicAuth.parse_basic_auth(conn),
:ok <- FieldHub.CouchService.authenticate(project, %Credentials{name: name, password: password}) do
conn
|> fetch_session()
|> put_session(:user, name)
|> put_session(:password, password)
else
_ ->
conn
|> Plug.BasicAuth.request_basic_auth()
|> halt()
end
end
end
To then setup my live view like this:
defmodule FieldHubWeb.MonitoringLive do
(...)
def mount(%{"project" => project}, %{"user" => user, "password" => password}, socket) do
credentials =
%CouchService.Credentials{
name: user,
password: password
}
Process.send(self(), :update, [])
{
:ok,
socket
|> assign(:stats, :loading)
|> assign(:project, project)
|> assign(:credentials, credentials)
}
end
def handle_info(:update, %{assigns: %{credentials: credentials, project: project}} = socket) do
stats =
credentials
|> Statistics.get_for_project(project)
Process.send_after(self(), :update, 1000)
{:noreply, assign(socket, :stats, stats)}
end
(...)
Further down, the Statistics module triggers a HTTP request towards the CouchDB:
def get_db_infos(%Credentials{} = credentials, project_name) do
response =
HTTPoison.get!(
"#{base_url()}/#{project_name}",
headers(credentials)
)
case response do
%{status_code: 200, body: body} ->
Jason.decode!(body)
%{status_code: 401} ->
{:error, 401}
%{status_code: 403} ->
{:error, 403}
end
end
So I want the username/password in my live view to run the CouchDB requests periodically. My main concern is basically |> put_session(:password, password) in the plug, which feels dangerous.
Did I miss something fundamental security wise? Or even if this is ok: Is my solution nevertheless an antipattern in some other respect?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #hex
- #security










Showing Posts 1 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
smon
I opted to rework the general setup based on what
phx.gen.authgenerates for ecto and PostgreSQL, basically stripping everything out that did not fit.