summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog.d/local-fetch-prevention.security1
-rw-r--r--lib/pleroma/object/containment.ex13
-rw-r--r--lib/pleroma/object/fetcher.ex4
-rw-r--r--test/pleroma/object/fetcher_test.exs7
4 files changed, 25 insertions, 0 deletions
diff --git a/changelog.d/local-fetch-prevention.security b/changelog.d/local-fetch-prevention.security
new file mode 100644
index 000000000..f72342316
--- /dev/null
+++ b/changelog.d/local-fetch-prevention.security
@@ -0,0 +1 @@
+Security: Block attempts to fetch activities from the local instance to prevent spoofing. \ No newline at end of file
diff --git a/lib/pleroma/object/containment.ex b/lib/pleroma/object/containment.ex
index f6106cb3f..77fac12c0 100644
--- a/lib/pleroma/object/containment.ex
+++ b/lib/pleroma/object/containment.ex
@@ -48,6 +48,19 @@ defmodule Pleroma.Object.Containment do
defp compare_uris(_id_uri, _other_uri), do: :error
@doc """
+ Checks whether an URL to fetch from is from the local server.
+
+ We never want to fetch from ourselves; if it's not in the database
+ it can't be authentic and must be a counterfeit.
+ """
+ def contain_local_fetch(id) do
+ case compare_uris(URI.parse(id), Pleroma.Web.Endpoint.struct_url()) do
+ :ok -> :error
+ _ -> :ok
+ end
+ end
+
+ @doc """
Checks that an imported AP object's actor matches the host it came from.
"""
def contain_origin(_id, %{"actor" => nil}), do: :error
diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex
index 41587c116..b54ef9ce5 100644
--- a/lib/pleroma/object/fetcher.ex
+++ b/lib/pleroma/object/fetcher.ex
@@ -148,6 +148,7 @@ defmodule Pleroma.Object.Fetcher do
with {:scheme, true} <- {:scheme, String.starts_with?(id, "http")},
{_, true} <- {:mrf, MRF.id_filter(id)},
+ {_, :ok} <- {:local_fetch, Containment.contain_local_fetch(id)},
{:ok, body} <- get_object(id),
{:ok, data} <- safe_json_decode(body),
:ok <- Containment.contain_origin_from_id(id, data) do
@@ -160,6 +161,9 @@ defmodule Pleroma.Object.Fetcher do
{:scheme, _} ->
{:error, "Unsupported URI scheme"}
+ {:local_fetch, _} ->
+ {:error, "Trying to fetch local resource"}
+
{:error, e} ->
{:error, e}
diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs
index 32689a68d..7ba5090e1 100644
--- a/test/pleroma/object/fetcher_test.exs
+++ b/test/pleroma/object/fetcher_test.exs
@@ -166,6 +166,13 @@ defmodule Pleroma.Object.FetcherTest do
)
end
+ test "it does not fetch from local instance" do
+ local_url = Pleroma.Web.Endpoint.url() <> "/objects/local_resource"
+
+ assert {:fetch, {:error, "Trying to fetch local resource"}} =
+ Fetcher.fetch_object_from_id(local_url)
+ end
+
test "it validates content-type headers according to ActivityPub spec" do
# Setup a mock for an object with invalid content-type
mock(fn