From e0546f188da23c9babb4589c2fc7286d4699cc0f Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Sat, 31 Oct 2026 15:37:41 +0400 Subject: [PATCH] fix(activitypub): do not require the personal inbox owner to be addressed Bridgy Fed delivers Follow and Accept to the personal inbox addressed only to Public. Any server can already address a local user directly, so the check gave no protection. Ported from Akkoma 2b885288f. Co-authored-by: Oneric --- changelog.d/personal-inbox-addressing.fix | 1 + .../activity_pub/activity_pub_controller.ex | 1 - lib/pleroma/web/activity_pub/utils.ex | 16 ----- .../activity_pub_controller_test.exs | 24 +++++++ test/pleroma/web/activity_pub/utils_test.exs | 68 ------------------- 5 files changed, 25 insertions(+), 85 deletions(-) create mode 100644 changelog.d/personal-inbox-addressing.fix diff --git a/changelog.d/personal-inbox-addressing.fix b/changelog.d/personal-inbox-addressing.fix new file mode 100644 index 000000000..9a2ba48a2 --- /dev/null +++ b/changelog.d/personal-inbox-addressing.fix @@ -0,0 +1 @@ +Accept activities delivered to a personal inbox that do not address the inbox owner (fixes Bridgy Fed follows) diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index dd5f6028f..a45f7bf27 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -341,7 +341,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do {:sender_exists, User.get_or_fetch_by_ap_id(params["actor"])}, {:recipient_active, true} <- {:recipient_active, recipient.is_active}, {:sender_active, true} <- {:sender_active, actor.is_active}, - true <- Utils.recipient_in_message(recipient, actor, params), params <- Utils.maybe_splice_recipient(recipient.ap_id, params) do Federator.incoming_ap_doc(params) json(conn, "ok") diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 0af4ceaf5..5c25f4c69 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -78,22 +78,6 @@ defmodule Pleroma.Web.ActivityPub.Utils do [params["to"], params["cc"], params["bto"], params["bcc"]] |> Enum.any?(&label_in_collection?(label, &1)) - @spec unaddressed_message?(map()) :: boolean() - def unaddressed_message?(params), - do: - [params["to"], params["cc"], params["bto"], params["bcc"]] - |> Enum.all?(fn - nil -> true - [] -> true - _ -> false - end) - - @spec recipient_in_message(User.t(), User.t(), map()) :: boolean() - def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params), - do: - label_in_message?(ap_id, params) || unaddressed_message?(params) || - User.following?(recipient, actor) - defp extract_list(target) when is_binary(target), do: [target] defp extract_list(lst) when is_list(lst), do: lst defp extract_list(_), do: [] diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs index 606d47c8d..e1376b460 100644 --- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs @@ -1872,6 +1872,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert Activity.get_by_ap_id(data["id"]) end + test "it accepts activities that do not address the inbox owner", %{conn: conn} do + user = insert(:user) + actor = insert(:user, local: false) + + data = %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "type" => "Follow", + "id" => "#{actor.ap_id}/follows/1", + "actor" => actor.ap_id, + "object" => user.ap_id, + "to" => ["https://www.w3.org/ns/activitystreams#Public"] + } + + conn = + conn + |> assign_valid_signature_for_actor(data["actor"]) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/inbox", data) + + assert "ok" == json_response(conn, 200) + ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) + assert Activity.get_by_ap_id(data["id"]) + end + test "it returns an error when receiving an activity sent to a deactivated user", %{ conn: conn, data: data diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index 93234a015..88c8a283b 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -406,74 +406,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do end end - describe "recipient_in_message/3" do - test "returns true when recipient in `to`" do - recipient = insert(:user) - actor = insert(:user) - assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id}) - - assert Utils.recipient_in_message( - recipient, - actor, - %{"to" => [recipient.ap_id], "cc" => ""} - ) - end - - test "returns true when recipient in `cc`" do - recipient = insert(:user) - actor = insert(:user) - assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id}) - - assert Utils.recipient_in_message( - recipient, - actor, - %{"cc" => [recipient.ap_id], "to" => ""} - ) - end - - test "returns true when recipient in `bto`" do - recipient = insert(:user) - actor = insert(:user) - assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id}) - - assert Utils.recipient_in_message( - recipient, - actor, - %{"bcc" => "", "bto" => [recipient.ap_id]} - ) - end - - test "returns true when recipient in `bcc`" do - recipient = insert(:user) - actor = insert(:user) - assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id}) - - assert Utils.recipient_in_message( - recipient, - actor, - %{"bto" => "", "bcc" => [recipient.ap_id]} - ) - end - - test "returns true when message without addresses fields" do - recipient = insert(:user) - actor = insert(:user) - assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id}) - - assert Utils.recipient_in_message( - recipient, - actor, - %{"btod" => "", "bccc" => [recipient.ap_id]} - ) - end - - test "returns false" do - recipient = insert(:user) - actor = insert(:user) - refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"}) - end - end - describe "lazy_put_activity_defaults/2" do test "returns map with id and published data" do note_activity = insert(:note_activity)