Reject events with long URIs and data URIs (#2536)

* Reject events with data URIs

* Reject events with URIs longer than 2,000 characters

* Update CHANGELOG.md
This commit is contained in:
Vini Brasil 2022-12-21 14:53:04 +01:00 committed by GitHub
parent ecd3ff276b
commit 5152e8d416
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 11 deletions

View File

@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file.
## Unreleased ## Unreleased
### Changed ### Changed
- Reject events with long URIs and data URIs plausible/analytics#2536
- Always show direct traffic in sources reports plausible/analytics#2531 - Always show direct traffic in sources reports plausible/analytics#2531
## v1.5.1 - 2022-12-06 ## v1.5.1 - 2022-12-06

View File

@ -57,6 +57,7 @@ defmodule Plausible.Ingestion.Request do
:pathname, :pathname,
:timestamp :timestamp
]) ])
|> Changeset.validate_length(:pathname, max: 2000)
|> Changeset.apply_action(nil) |> Changeset.apply_action(nil)
{:error, :invalid_json} -> {:error, :invalid_json} ->
@ -128,18 +129,15 @@ defmodule Plausible.Ingestion.Request do
end end
end end
@disallowed_schemes ~w(data)
defp put_uri(changeset, %{} = request_body) do defp put_uri(changeset, %{} = request_body) do
url = request_body["u"] || request_body["url"] with url when is_binary(url) <- request_body["u"] || request_body["url"],
%URI{} = uri when uri.scheme not in @disallowed_schemes <- URI.parse(url) do
case url do Changeset.put_change(changeset, :uri, uri)
nil -> else
Changeset.add_error(changeset, :url, "is required") nil -> Changeset.add_error(changeset, :url, "is required")
%URI{} -> Changeset.add_error(changeset, :url, "scheme is not allowed")
url when is_binary(url) -> _ -> Changeset.add_error(changeset, :url, "must be a string")
Changeset.put_change(changeset, :uri, URI.parse(url))
_ ->
Changeset.add_error(changeset, :url, "must be a string")
end end
end end

View File

@ -202,4 +202,30 @@ defmodule Plausible.Ingestion.RequestTest do
assert request.query_params["foo"] == "bar" assert request.query_params["foo"] == "bar"
assert request.query_params["baz"] == "bam" assert request.query_params["baz"] == "bam"
end end
test "returns validation error when using data uris" do
payload = %{
name: "pageview",
domain: "dummy.site",
url: "data:text/html,%3Cscript%3Ealert%28%27hi%27%29%3B%3C%2Fscript%3E"
}
conn = build_conn(:post, "/api/events", payload)
assert {:error, changeset} = Request.build(conn)
assert {"scheme is not allowed", _} = changeset.errors[:url]
end
test "returns validation error when pathname is too long" do
long_string = for _ <- 1..5000, do: "a", into: ""
payload = %{
name: "pageview",
domain: "dummy.site",
url: "https://dummy.site/#{long_string}"
}
conn = build_conn(:post, "/api/events", payload)
assert {:error, changeset} = Request.build(conn)
assert {"should be at most %{count} character(s)", _} = changeset.errors[:pathname]
end
end end