fix(submit): allowlist switch_tab values instead of trusting client input
`handle_event("switch_tab", ...)` ran `String.to_existing_atom/1` on
the raw `tab` value from the browser, so a stale, forged, or
mistyped client event with any unknown string crashed the LiveView
with `ArgumentError: not an already existing atom`.
Compares against an explicit `@valid_tabs` allowlist (`:single`,
`:csv`, `:adif`) — known values switch the active tab, anything
else is ignored.
This commit is contained in:
parent
c17f912622
commit
90bf44ce90
2 changed files with 34 additions and 2 deletions
|
|
@ -54,10 +54,20 @@ defmodule MicrowavepropWeb.SubmitLive do
|
|||
end
|
||||
end
|
||||
|
||||
@valid_tabs ~w(single csv adif)a
|
||||
|
||||
@impl true
|
||||
def handle_event("switch_tab", %{"tab" => tab}, socket) do
|
||||
socket = assign(socket, active_tab: String.to_existing_atom(tab))
|
||||
{:noreply, MicrowavepropWeb.LiveStashGuard.stash(socket)}
|
||||
case Enum.find(@valid_tabs, &(Atom.to_string(&1) == tab)) do
|
||||
nil ->
|
||||
# Stale or forged client event — ignore instead of crashing the
|
||||
# LiveView via String.to_existing_atom/1.
|
||||
{:noreply, socket}
|
||||
|
||||
atom ->
|
||||
socket = assign(socket, active_tab: atom)
|
||||
{:noreply, MicrowavepropWeb.LiveStashGuard.stash(socket)}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"contact" => contact_params}, socket) do
|
||||
|
|
|
|||
|
|
@ -43,6 +43,28 @@ defmodule MicrowavepropWeb.SubmitLiveTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "switch_tab" do
|
||||
test "ignores an unknown tab string instead of crashing the LiveView", %{conn: conn} do
|
||||
{:ok, lv, _html} = live(conn, ~p"/submit")
|
||||
|
||||
# An unknown tab name used to flow into String.to_existing_atom/1
|
||||
# and bring the LiveView down. We expect the event to be a no-op
|
||||
# and the process to stay alive.
|
||||
render_hook(lv, "switch_tab", %{"tab" => "definitely-not-a-tab-#{System.unique_integer()}"})
|
||||
|
||||
assert Process.alive?(lv.pid)
|
||||
end
|
||||
|
||||
test "honors a known tab name", %{conn: conn} do
|
||||
{:ok, lv, _html} = live(conn, ~p"/submit")
|
||||
|
||||
html = render_hook(lv, "switch_tab", %{"tab" => "csv"})
|
||||
|
||||
# Active tab moved to CSV — the CSV section's heading is now visible.
|
||||
assert html =~ "CSV"
|
||||
end
|
||||
end
|
||||
|
||||
describe "validate" do
|
||||
test "shows validation errors on change", %{conn: conn} do
|
||||
{:ok, lv, _html} = live(conn, ~p"/submit")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue