Convert to an Plug called InboxGuard

This commit is contained in:
Mark Felder 2024-08-29 14:16:59 -04:00
parent 06deacd58e
commit 16a9b34876
5 changed files with 91 additions and 28 deletions

View file

@ -85,6 +85,18 @@ defmodule Pleroma.Constants do
]
)
const(allowed_activity_types_from_strangers,
do: [
"Block",
"Create",
"Flag",
"Follow",
"Like",
"Move",
"React"
]
)
# basic regex, just there to weed out potential mistakes
# https://datatracker.ietf.org/doc/html/rfc2045#section-5.1
const(mime_regex,

View file

@ -294,19 +294,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end
def inbox(%{assigns: %{valid_signature: false}} = conn, params) do
case unknown_delete?(params) do
true ->
:ok
false ->
Federator.incoming_ap_doc(%{
method: conn.method,
req_headers: conn.req_headers,
request_path: conn.request_path,
params: params,
query_string: conn.query_string
})
end
Federator.incoming_ap_doc(%{
method: conn.method,
req_headers: conn.req_headers,
request_path: conn.request_path,
params: params,
query_string: conn.query_string
})
json(conn, "ok")
end
@ -564,17 +558,4 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|> json(UserView.render("featured.json", %{user: user}))
end
end
defp unknown_delete?(
%{
"type" => "Delete"
} = data
) do
case data |> Pleroma.Object.Containment.get_actor() |> User.get_cached_by_ap_id() do
%User{} -> false
_ -> true
end
end
defp unknown_delete?(_), do: false
end

View file

@ -0,0 +1,66 @@
# 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.InboxGuardPlug do
import Plug.Conn
import Pleroma.Constants, only: [allowed_activity_types_from_strangers: 0]
alias Pleroma.Config
alias Pleroma.User
def init(options) do
options
end
def call(%{assigns: %{valid_signature: true}} = conn, _opts) do
conn
end
def call(conn, _opts) do
with {_, true} <- {:federating, Config.get!([:instance, :federating])},
true <- known_actor?(conn) do
conn
else
{:federating, false} ->
conn
|> json(403, "Not federating")
_ ->
conn
|> filter_from_strangers()
end
end
# If signature failed but we know this actor we should
# accept it as we may only need to refetch their public key
# during processing
defp known_actor?(%{body_params: data}) do
case Pleroma.Object.Containment.get_actor(data) |> User.get_cached_by_ap_id() do
%User{} -> true
_ -> false
end
end
# Only permit a subset of activity types from strangers
# or else it will add actors you've never interacted with
# to the database
defp filter_from_strangers(%{body_params: %{"type" => type}} = conn) do
with true <- type in allowed_activity_types_from_strangers() do
conn
else
_ ->
conn
|> json(400, "Invalid activity type for an unknown actor")
end
end
defp json(conn, status, resp) do
json_resp = Jason.encode!(resp)
conn
|> put_resp_content_type("application/json")
|> resp(status, json_resp)
|> halt()
end
end

View file

@ -217,6 +217,10 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)
end
pipeline :inbox_guard do
plug(Pleroma.Web.Plugs.InboxGuardPlug)
end
pipeline :static_fe do
plug(Pleroma.Web.Plugs.StaticFEPlug)
end
@ -920,7 +924,7 @@ defmodule Pleroma.Web.Router do
end
scope "/", Pleroma.Web.ActivityPub do
pipe_through(:activitypub)
pipe_through([:activitypub, :inbox_guard])
post("/inbox", ActivityPubController, :inbox)
post("/users/:nickname/inbox", ActivityPubController, :inbox)
end

View file

@ -700,7 +700,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> assign(:valid_signature, false)
|> put_req_header("content-type", "application/activity+json")
|> post("/inbox", params)
|> json_response(200)
|> json_response(400)
assert all_enqueued() == []
end