From 4337e0eb1b40942c7860b9d32e5ecf1ddafdc0ba Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 1 May 2026 12:33:26 +0400 Subject: [PATCH] Fail closed on unresolved signed payloads Reject unknown remote Update targets and invalidate signed payloads when their signer identity cannot be mapped, avoiding crashes and fail-open signature state. --- .../object_validators/update_validator.ex | 4 ++++ .../plugs/mapped_signature_to_identity_plug.ex | 4 ++-- .../object_validators/update_handling_test.exs | 17 +++++++++++++++++ .../mapped_signature_to_identity_plug_test.exs | 12 ++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/object_validators/update_validator.ex b/lib/pleroma/web/activity_pub/object_validators/update_validator.ex index 5586b74cf..ad3c0e3e2 100644 --- a/lib/pleroma/web/activity_pub/object_validators/update_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/update_validator.ex @@ -101,6 +101,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateValidator do |> add_error(:object, "Can't be updated by this actor") end + nil -> + cng + |> add_error(:object, "Can't be updated by this actor") + true -> cng |> add_error(:object, "Update is neither for Object or Actor") diff --git a/lib/pleroma/web/plugs/mapped_signature_to_identity_plug.ex b/lib/pleroma/web/plugs/mapped_signature_to_identity_plug.ex index c6d531086..a688b1780 100644 --- a/lib/pleroma/web/plugs/mapped_signature_to_identity_plug.ex +++ b/lib/pleroma/web/plugs/mapped_signature_to_identity_plug.ex @@ -32,8 +32,8 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlug do # remove me once testsuite uses mapped capabilities instead of what we do now {:user, nil} -> Logger.debug("Failed to map identity from signature (lookup failure)") - Logger.debug("key_id=#{inspect(key_id_from_conn(conn))}, actor=#{actor}") - conn + Logger.debug("key_id=#{inspect(key_id_from_conn(conn))}, actor=#{inspect(actor)}") + assign(conn, :valid_signature, false) end end diff --git a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs index f04f9cc61..9dec315b3 100644 --- a/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/update_handling_test.exs @@ -90,6 +90,23 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do refute cng.valid? assert Keyword.has_key?(cng.errors, :object) end + + test "returns an error if the remote update target IRI is unknown" do + remote_user = insert(:user, local: false, ap_id: "https://example.com/users/alice") + + update = %{ + "type" => "Update", + "actor" => remote_user.ap_id, + "id" => "https://example.com/activities/update-unknown-object-iri", + "to" => ["https://www.w3.org/ns/activitystreams#Public"], + "cc" => [], + "object" => "https://example.com/objects/unknown-iri" + } + + assert {:error, %Ecto.Changeset{} = cng} = ObjectValidator.validate(update, local: false) + refute cng.valid? + assert Keyword.has_key?(cng.errors, :object) + end end describe "update note" do diff --git a/test/pleroma/web/plugs/mapped_signature_to_identity_plug_test.exs b/test/pleroma/web/plugs/mapped_signature_to_identity_plug_test.exs index 81c6b0c5d..df713762c 100644 --- a/test/pleroma/web/plugs/mapped_signature_to_identity_plug_test.exs +++ b/test/pleroma/web/plugs/mapped_signature_to_identity_plug_test.exs @@ -58,4 +58,16 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do assert conn.assigns.valid_signature == false refute Map.has_key?(conn.assigns, :user) end + + test "it considers a mapped identity to be invalid when embedded actor identity cannot be found" do + actor = "http://niu.moe/users/rye" + + conn = + build_conn(:post, "/doesntmattter", %{"actor" => %{"id" => actor}}) + |> set_signature(actor) + |> MappedSignatureToIdentityPlug.call(%{}) + + assert conn.assigns.valid_signature == false + refute Map.has_key?(conn.assigns, :user) + end end