Protected against counterfeit local docs being posted

Only possible if actor keys leaked first
thus log with alert level
This commit is contained in:
Oneric 2024-12-30 17:59:21 +01:00
parent 4231345f4e
commit d68a5f6c56
3 changed files with 48 additions and 5 deletions

View file

@ -94,6 +94,7 @@ def perform(:incoming_ap_doc, params) do
with nil <- Activity.normalize(params["id"]),
{_, :ok} <-
{:correct_origin?, Containment.contain_origin_from_id(actor, params)},
{_, :ok, _} <- {:local, Containment.contain_local_fetch(actor), actor},
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
{:ok, activity}
else
@ -101,6 +102,13 @@ def perform(:incoming_ap_doc, params) do
Logger.debug("Origin containment failure for #{params["id"]}")
{:error, :origin_containment_failed}
{:local, _, actor} ->
Logger.alert(
"Received incoming AP doc with valid signature for local actor #{actor}! Likely key leak!\n#{inspect(params)}"
)
{:error, :origin_containment_failed}
%Activity{} ->
Logger.debug("Already had #{params["id"]}")
{:error, :already_present}

View file

@ -16,7 +16,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Endpoint
alias Pleroma.Workers.ReceiverWorker
@ -1113,7 +1112,8 @@ test "it clears `unreachable` federation status of the sender", %{conn: conn, da
end
test "it removes all follower collections but actor's", %{conn: conn} do
[actor, recipient] = insert_pair(:user)
actor = insert(:user, local: false)
recipient = insert(:user, local: true)
actor = with_signing_key(actor)
to = [
@ -1127,7 +1127,7 @@ test "it removes all follower collections but actor's", %{conn: conn} do
data = %{
"@context" => ["https://www.w3.org/ns/activitystreams"],
"type" => "Create",
"id" => Utils.generate_activity_id(),
"id" => actor.ap_id <> "/create/12345",
"to" => to,
"cc" => cc,
"actor" => actor.ap_id,
@ -1137,7 +1137,7 @@ test "it removes all follower collections but actor's", %{conn: conn} do
"cc" => cc,
"content" => "It's a note",
"attributedTo" => actor.ap_id,
"id" => Utils.generate_object_id()
"id" => actor.ap_id <> "/note/12345"
}
}

View file

@ -7,13 +7,16 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do
use Oban.Testing, repo: Pleroma.Repo
@moduletag :mocked
import ExUnit.CaptureLog
import Mock
import Pleroma.Factory
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Workers.ReceiverWorker
test "it ignores MRF reject" do
params = insert(:note).data
user = insert(:user, local: false)
params = insert(:note, user: user, data: %{"id" => user.ap_id <> "/note/1"}).data
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
handle_incoming: fn _ -> {:reject, "MRF"} end do
@ -23,4 +26,36 @@ test "it ignores MRF reject" do
})
end
end
test "it errors on receiving local documents" do
actor = insert(:user, local: true)
recipient = insert(:user, local: true)
to = [recipient.ap_id]
cc = []
params = %{
"@context" => ["https://www.w3.org/ns/activitystreams"],
"type" => "Create",
"id" => Utils.generate_activity_id(),
"to" => to,
"cc" => cc,
"actor" => actor.ap_id,
"object" => %{
"type" => "Note",
"to" => to,
"cc" => cc,
"content" => "It's a note",
"attributedTo" => actor.ap_id,
"id" => Utils.generate_object_id()
}
}
assert capture_log(fn ->
assert {:discard, :origin_containment_failed} ==
ReceiverWorker.perform(%Oban.Job{
args: %{"op" => "incoming_ap_doc", "params" => params}
})
end) =~ "[alert] Received incoming AP doc with valid signature for local actor"
end
end