Don't crash ingesting >1M bytes payloads (#4872)

* Don't crash ingesting >1M bytes payloads

* Format
This commit is contained in:
hq1 2024-12-03 12:50:47 +01:00 committed by GitHub
parent 133423f7e6
commit a47a9adfbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 4 deletions

View File

@ -112,10 +112,12 @@ defmodule Plausible.Ingestion.Request do
defp parse_body(conn) do defp parse_body(conn) do
case conn.body_params do case conn.body_params do
%Plug.Conn.Unfetched{} -> %Plug.Conn.Unfetched{} ->
{:ok, body, _conn} = Plug.Conn.read_body(conn) with max_length <- conn.assigns[:read_body_limit] || 1_000_000,
{:ok, body, _conn} <-
case Jason.decode(body) do Plug.Conn.read_body(conn, length: max_length, read_length: max_length),
{:ok, params} when is_map(params) -> {:ok, params} {:ok, params} when is_map(params) <- Jason.decode(body) do
{:ok, params}
else
_ -> {:error, :invalid_json} _ -> {:error, :invalid_json}
end end

View File

@ -429,6 +429,31 @@ defmodule Plausible.Ingestion.RequestTest do
assert changeset.errors[:request] assert changeset.errors[:request]
end end
test "long body length" do
payload = """
{
"name": "pageview",
"domain": "dummy.site",
"url": "#{:binary.copy("a", 1_000)}"
}
"""
within_read_limit =
:post
|> build_conn("/api/events", payload)
|> Request.build()
assert {:ok, _} = within_read_limit
exceeding_read_limit =
:post
|> build_conn("/api/events", payload)
|> Plug.Conn.assign(:read_body_limit, 800)
|> Request.build()
assert {:error, _} = exceeding_read_limit
end
@tag :ee_only @tag :ee_only
test "encodable" do test "encodable" do
params = %{ params = %{