Security: Validate blog controller inputs (page param, blog ID)

Ran a claude /security-review, fixed two vulnerabilities

  Use a plug to resolve blog_id, returning a clean 404 for unknown blogs
  instead of raising with inspect(). Parse page param with Integer.parse
  so invalid values (non-numeric, negative, zero) fall back to page 1
  instead of crashing. Add 5 tests covering these cases.a
This commit is contained in:
Willem van den Ende
2026-03-17 12:17:29 +00:00
parent c8bc3ea197
commit 6887ae4087
2 changed files with 56 additions and 11 deletions
@@ -1,9 +1,11 @@
defmodule FirehoseWeb.BlogController do
use FirehoseWeb, :controller
def index(conn, %{"blog_id" => blog_id} = params) do
blog = resolve_blog!(blog_id)
page = String.to_integer(params["page"] || "1")
plug :resolve_blog
def index(conn, params) do
blog = conn.assigns.blog
page = parse_page(params["page"])
result = blog.paginate(page)
render(conn, :index,
@@ -17,8 +19,8 @@ defmodule FirehoseWeb.BlogController do
)
end
def show(conn, %{"blog_id" => blog_id, "slug" => slug}) do
blog = resolve_blog!(blog_id)
def show(conn, %{"slug" => slug}) do
blog = conn.assigns.blog
post = blog.get_post!(slug)
render(conn, :show,
@@ -28,8 +30,8 @@ defmodule FirehoseWeb.BlogController do
)
end
def tag(conn, %{"blog_id" => blog_id, "tag" => tag}) do
blog = resolve_blog!(blog_id)
def tag(conn, %{"tag" => tag}) do
blog = conn.assigns.blog
posts = blog.posts_by_tag(tag)
render(conn, :tag,
@@ -41,10 +43,25 @@ defmodule FirehoseWeb.BlogController do
)
end
defp resolve_blog!("engineering"), do: Firehose.EngineeringBlog
defp resolve_blog!("releases"), do: Firehose.ReleaseNotes
defp resolve_blog(%{params: %{"blog_id" => "engineering"}} = conn, _opts),
do: assign(conn, :blog, Firehose.EngineeringBlog)
defp resolve_blog!(id) do
raise Blogex.NotFoundError, "unknown blog: #{inspect(id)}"
defp resolve_blog(%{params: %{"blog_id" => "releases"}} = conn, _opts),
do: assign(conn, :blog, Firehose.ReleaseNotes)
defp resolve_blog(conn, _opts) do
conn
|> put_status(:not_found)
|> put_view(FirehoseWeb.ErrorHTML)
|> render(:"404")
|> halt()
end
defp parse_page(nil), do: 1
defp parse_page(str) do
case Integer.parse(str) do
{page, ""} when page > 0 -> page
_ -> 1
end
end
end