Add some hard limits on inserted activities. See merge request pleroma/pleroma!595tags/v0.9.9
@@ -98,7 +98,8 @@ config :pleroma, :instance, | |||||
name: "Pleroma", | name: "Pleroma", | ||||
email: "example@example.com", | email: "example@example.com", | ||||
description: "A Pleroma instance, an alternative fediverse server", | description: "A Pleroma instance, an alternative fediverse server", | ||||
limit: 5000, | |||||
limit: 5_000, | |||||
remote_limit: 100_000, | |||||
upload_limit: 16_000_000, | upload_limit: 16_000_000, | ||||
avatar_upload_limit: 2_000_000, | avatar_upload_limit: 2_000_000, | ||||
background_upload_limit: 4_000_000, | background_upload_limit: 4_000_000, | ||||
@@ -63,6 +63,7 @@ config :pleroma, Pleroma.Mailer, | |||||
* `email`: Email used to reach an Administrator/Moderator of the instance | * `email`: Email used to reach an Administrator/Moderator of the instance | ||||
* `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance`` | * `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance`` | ||||
* `limit`: Posts character limit (CW/Subject included in the counter) | * `limit`: Posts character limit (CW/Subject included in the counter) | ||||
* `remote_limit`: Hard character limit beyond which remote posts will be dropped. | |||||
* `upload_limit`: File size limit of uploads (except for avatar, background, banner) | * `upload_limit`: File size limit of uploads (except for avatar, background, banner) | ||||
* `avatar_upload_limit`: File size limit of user’s profile avatars | * `avatar_upload_limit`: File size limit of user’s profile avatars | ||||
* `background_upload_limit`: File size limit of user’s profile backgrounds | * `background_upload_limit`: File size limit of user’s profile backgrounds | ||||
@@ -56,10 +56,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||||
end | end | ||||
end | end | ||||
defp check_remote_limit(%{"object" => %{"content" => content}}) do | |||||
limit = Pleroma.Config.get([:instance, :remote_limit]) | |||||
String.length(content) <= limit | |||||
end | |||||
defp check_remote_limit(_), do: true | |||||
def insert(map, local \\ true) when is_map(map) do | def insert(map, local \\ true) when is_map(map) do | ||||
with nil <- Activity.normalize(map), | with nil <- Activity.normalize(map), | ||||
map <- lazy_put_activity_defaults(map), | map <- lazy_put_activity_defaults(map), | ||||
:ok <- check_actor_is_active(map["actor"]), | :ok <- check_actor_is_active(map["actor"]), | ||||
{_, true} <- {:remote_limit_error, check_remote_limit(map)}, | |||||
{:ok, map} <- MRF.filter(map), | {:ok, map} <- MRF.filter(map), | ||||
:ok <- insert_full_object(map) do | :ok <- insert_full_object(map) do | ||||
{recipients, _, _} = get_recipients(map) | {recipients, _, _} = get_recipients(map) | ||||
@@ -31,6 +31,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do | |||||
end | end | ||||
describe "insertion" do | describe "insertion" do | ||||
test "drops activities beyond a certain limit" do | |||||
limit = Pleroma.Config.get([:instance, :remote_limit]) | |||||
random_text = | |||||
:crypto.strong_rand_bytes(limit + 1) | |||||
|> Base.encode64() | |||||
|> binary_part(0, limit + 1) | |||||
data = %{ | |||||
"ok" => true, | |||||
"object" => %{ | |||||
"content" => random_text | |||||
} | |||||
} | |||||
assert {:error, {:remote_limit_error, _}} = ActivityPub.insert(data) | |||||
end | |||||
test "returns the activity if one with the same id is already in" do | test "returns the activity if one with the same id is already in" do | ||||
activity = insert(:note_activity) | activity = insert(:note_activity) | ||||
{:ok, new_activity} = ActivityPub.insert(activity.data) | {:ok, new_activity} = ActivityPub.insert(activity.data) | ||||