Containment: Never fetch locally

This commit is contained in:
Lain Soykaf 2025-03-11 16:37:17 +04:00
parent b0c2ec5fb9
commit 51c1d6fb2d
4 changed files with 25 additions and 0 deletions

View file

@ -0,0 +1 @@
Security: Block attempts to fetch activities from the local instance to prevent spoofing.

View file

@ -47,6 +47,19 @@ defmodule Pleroma.Object.Containment do
defp compare_uris(%URI{host: host} = _id_uri, %URI{host: host} = _other_uri), do: :ok
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.
"""

View file

@ -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}

View file

@ -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