fix(federation): do not deliver to instances rejected by SimplePolicy
Public activities went to every inbox, so followers on an instance in the SimplePolicy reject list still got our posts. With authorized fetch mode on, signed fetches from those instances were also accepted, unless the instance was in :instance, :rejected_instances too. Check the SimplePolicy reject and accept lists for deliveries and signed fetches, when the policy is enabled. Quarantine keeps its meaning (no private activities). An inbox without a host no longer crashes. Based on the Akkoma changes 90c4785b8, ca000f830, 03662501c and d2b0d8647. Co-authored-by: FloatingGhost <hannah@coffee-and-dreams.uk> Co-authored-by: Atsuko Karagi <atsuko.karagi@localhost>
This commit is contained in:
parent
90eb5e4015
commit
a766335679
9 changed files with 177 additions and 18 deletions
|
|
@ -139,4 +139,37 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
|
|||
type: :group
|
||||
}
|
||||
end
|
||||
|
||||
describe "instance_allowed?/1" do
|
||||
setup do: clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
setup do: clear_config([:mrf_simple, :reject], [{"rejected.example", "spam"}])
|
||||
setup do: clear_config([:mrf_simple, :accept], [])
|
||||
|
||||
test "is false for hosts rejected by SimplePolicy, including subdomains" do
|
||||
clear_config([:mrf_simple, :reject], [{"*.rejected.example", "spam"}])
|
||||
|
||||
refute MRF.instance_allowed?("rejected.example")
|
||||
refute MRF.instance_allowed?("sub.rejected.example")
|
||||
assert MRF.instance_allowed?("fine.example")
|
||||
end
|
||||
|
||||
test "only allows accepted hosts when SimplePolicy has an accept list" do
|
||||
clear_config([:mrf_simple, :accept], [{"friend.example", ""}])
|
||||
|
||||
assert MRF.instance_allowed?("friend.example")
|
||||
refute MRF.instance_allowed?("stranger.example")
|
||||
end
|
||||
|
||||
test "ignores the SimplePolicy lists when the policy is not enabled" do
|
||||
clear_config([:mrf, :policies], [])
|
||||
clear_config([:mrf_simple, :accept], [{"friend.example", ""}])
|
||||
|
||||
assert MRF.instance_allowed?("rejected.example")
|
||||
assert MRF.instance_allowed?("stranger.example")
|
||||
end
|
||||
|
||||
test "is false without a host" do
|
||||
refute MRF.instance_allowed?(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,8 +32,26 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
refute Publisher.should_federate?(nil, true)
|
||||
end
|
||||
|
||||
test "it returns true when public is true" do
|
||||
assert Publisher.should_federate?(false, true)
|
||||
test "it returns true for public activities to quarantined instances" do
|
||||
clear_config([:instance, :quarantined_instances], [{"quarantined.example", ""}])
|
||||
|
||||
assert Publisher.should_federate?("https://quarantined.example/inbox", true)
|
||||
refute Publisher.should_federate?("https://quarantined.example/inbox", false)
|
||||
end
|
||||
|
||||
test "it returns false for instances rejected by SimplePolicy, even for public activities" do
|
||||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
clear_config([:mrf_simple, :reject], [{"rejected.example", ""}])
|
||||
|
||||
refute Publisher.should_federate?("https://rejected.example/inbox", true)
|
||||
refute Publisher.should_federate?("https://rejected.example/inbox", false)
|
||||
assert Publisher.should_federate?("https://fine.example/inbox", true)
|
||||
end
|
||||
|
||||
test "it returns false for inboxes without a host" do
|
||||
clear_config([:instance, :quarantined_instances], [{"quarantined.example", ""}])
|
||||
|
||||
refute Publisher.should_federate?("inbox", false)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -204,6 +222,32 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
)
|
||||
end
|
||||
|
||||
test "doesn't publish a public activity to instances rejected by SimplePolicy" do
|
||||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
clear_config([:mrf_simple, :reject], [{"rejected.example", "spam"}])
|
||||
|
||||
actor = insert(:user)
|
||||
|
||||
for host <- ["rejected.example", "fine.example"] do
|
||||
follower = insert(:user, local: false, inbox: "https://#{host}/users/nick/inbox")
|
||||
{:ok, _, _} = Pleroma.User.follow(follower, actor)
|
||||
end
|
||||
|
||||
actor = refresh_record(actor)
|
||||
|
||||
note_activity =
|
||||
insert(:note_activity, user: actor, recipients: [@as_public, actor.follower_address])
|
||||
|
||||
assert :ok == Publisher.publish(actor, note_activity)
|
||||
|
||||
inboxes =
|
||||
all_enqueued(worker: "Pleroma.Workers.PublisherWorker")
|
||||
|> Enum.map(& &1.args["params"]["inbox"])
|
||||
|
||||
assert "https://fine.example/users/nick/inbox" in inboxes
|
||||
refute "https://rejected.example/users/nick/inbox" in inboxes
|
||||
end
|
||||
|
||||
test "Publishes a non-public activity to non-quarantined instances." do
|
||||
Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}])
|
||||
|
||||
|
|
|
|||
38
test/pleroma/web/plugs/http_signature_plug_mrf_test.exs
Normal file
38
test/pleroma/web/plugs/http_signature_plug_mrf_test.exs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Plugs.HTTPSignaturePlugMRFTest do
|
||||
# Not async: the MRF settings are global config.
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.StaticStubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.StubbedHTTPSignaturesMock, as: HTTPSignaturesMock
|
||||
alias Pleroma.Web.Plugs.HTTPSignaturePlug
|
||||
|
||||
import Mox
|
||||
import Phoenix.Controller, only: [put_format: 2]
|
||||
import Plug.Conn
|
||||
|
||||
setup do: clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
setup do: clear_config([:mrf_simple, :reject], [{"mastodon.example.org", "no reason"}])
|
||||
|
||||
defp signed_get(actor) do
|
||||
ConfigMock
|
||||
|> expect(:get, fn [:activitypub, :authorized_fetch_mode], false -> true end)
|
||||
|> expect(:get, fn [:instance, :rejected_instances] -> [] end)
|
||||
|
||||
HTTPSignaturesMock
|
||||
|> expect(:validate_conn, fn _ -> true end)
|
||||
|
||||
build_conn(:get, "/doesntmattter", %{"actor" => actor})
|
||||
|> put_req_header("signature", "keyId=\"#{actor}#main-key")
|
||||
|> put_format("activity+json")
|
||||
|> HTTPSignaturePlug.call(%{})
|
||||
end
|
||||
|
||||
test "rejects signed requests from instances rejected by SimplePolicy" do
|
||||
assert signed_get("http://mastodon.example.org/users/admin").halted
|
||||
refute signed_get("http://allowed.example.org/users/admin").halted
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue