Restrict Masto statuses API to Create and Announce activities

If the id of another activity type was used
it would show the post referenced by the activity
but wrongly attributing it to the activity actor
instead of the actual author.

E.g. ids of like activities can be obtained from
pagiantion info of the favourites endpoint.
For all other activity types the id would need to be guessed
which is considered practically infeasible for Flake UUIDs.

This should’ve been mostly harmless in practice, since:
  - since the activity has the same context as the original post,
    both the original and misattributed duplicate will show up in the
    same thread
  - only posts liked by a user can be misattributed to them,
    presumably making it hard/impossible to associate someone with
    content they disagree with
  - by default only the liking user themself can view their like history
    and therefore obtain IDs for their like activities.
    Notably though, there is a user seting to allow anyone to browse
    ones like history and therefore obtain like IDs. However, since
    akkoma-fe has no support for actually displaying those, there might
    be no actual users of this features.
This commit is contained in:
Oneric 2025-10-09 00:00:00 +00:00
parent 06a0cf4278
commit 0c9bb0594a
2 changed files with 17 additions and 0 deletions

View file

@ -262,7 +262,12 @@ def update(%{assigns: %{user: user}, body_params: body_params} = conn, %{id: id}
@doc "GET /api/v1/statuses/:id"
def show(%{assigns: %{user: user}} = conn, %{id: id} = params) do
# Announces are handled as normal statuses in MastoAPI, they just put the reblogged post
# in a "reblog" subproperty which clients the use for display. Creates are trivially ok.
# Everything else isnt a status as far as MastoAPI is concerned and
# would show up buggy since its not expected by our JSON render, thus reject.
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
type when type in ["Create", "Announce"] <- activity.data["type"],
true <- Visibility.visible_for_user?(activity, user) do
try_render(conn, "show.json",
activity: activity,

View file

@ -857,6 +857,18 @@ test "get a status" do
assert id == to_string(activity.id)
end
test "rejects non-Create, non-Announce activity id" do
%{conn: conn} = oauth_access(["read:statuses"])
activity = insert(:note_activity)
like_user = insert(:user)
{:ok, like_activity} = CommonAPI.favorite(like_user, activity.id)
conn = get(conn, "/api/v1/statuses/#{like_activity.id}")
assert %{"error" => _} = json_response_and_validate_schema(conn, 404)
end
defp local_and_remote_activities do
local = insert(:note_activity)
remote = insert(:note_activity, local: false)