diff --git a/CHANGELOG.md b/CHANGELOG.md index eacba0208..feac7b1c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Applying ConcurrentLimiter settings via AdminAPI - User login failures if their `notification_settings` were in a NULL state. - Mix task `pleroma.user delete_activities` query transaction timeout is now :infinity +- MRF (`SimplePolicy`): Embedded objects are now checked. If any embedded object would be rejected, its parent is rejected. This fixes Announces leaking posts from blocked domains. - Fixed some Markdown issues, including trailing slash in links. ## [2.3.0] - 2020-03-01 diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index 62024c58c..d40348cb1 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -177,6 +177,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do defp check_banner_removal(_actor_info, object), do: {:ok, object} + defp check_object(%{"object" => object} = activity) do + with {:ok, _object} <- filter(object) do + {:ok, activity} + end + end + + defp check_object(object), do: {:ok, object} + @impl true def filter(%{"type" => "Delete", "actor" => actor} = object) do %{host: actor_host} = URI.parse(actor) @@ -202,7 +210,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do {:ok, object} <- check_media_nsfw(actor_info, object), {:ok, object} <- check_ftl_removal(actor_info, object), {:ok, object} <- check_followers_only(actor_info, object), - {:ok, object} <- check_report_removal(actor_info, object) do + {:ok, object} <- check_report_removal(actor_info, object), + {:ok, object} <- check_object(object) do {:ok, object} else {:reject, nil} -> {:reject, "[SimplePolicy]"} @@ -227,6 +236,19 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do end end + def filter(object) when is_binary(object) do + uri = URI.parse(object) + + with {:ok, object} <- check_accept(uri, object), + {:ok, object} <- check_reject(uri, object) do + {:ok, object} + else + {:reject, nil} -> {:reject, "[SimplePolicy]"} + {:reject, _} = e -> e + _ -> {:reject, "[SimplePolicy]"} + end + end + def filter(object), do: {:ok, object} @impl true diff --git a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs index 5c0aff26e..9c263c7e6 100644 --- a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs @@ -254,6 +254,30 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do assert {:reject, _} = SimplePolicy.filter(remote_user) end + + test "reject Announce when object would be rejected" do + clear_config([:mrf_simple, :reject], ["blocked.tld"]) + + announce = %{ + "type" => "Announce", + "actor" => "https://okay.tld/users/alice", + "object" => %{"type" => "Note", "actor" => "https://blocked.tld/users/bob"} + } + + assert {:reject, _} = SimplePolicy.filter(announce) + end + + test "reject by URI object" do + clear_config([:mrf_simple, :reject], ["blocked.tld"]) + + announce = %{ + "type" => "Announce", + "actor" => "https://okay.tld/users/alice", + "object" => "https://blocked.tld/activities/1" + } + + assert {:reject, _} = SimplePolicy.filter(announce) + end end describe "when :followers_only" do