Commit dfcfb184 authored by kaniini's avatar kaniini
Browse files

activitypub: transmogrifier: make deletes secure

parent b1a6e8d8
Pipeline #4548 failed with stages
in 3 minutes and 5 seconds
...@@ -467,15 +467,20 @@ def handle_incoming( ...@@ -467,15 +467,20 @@ def handle_incoming(
end end
end end
# TODO: Make secure. # TODO: We presently assume that any actor on the same origin domain as the object being
# deleted has the rights to delete that object. A better way to validate whether or not
# the object should be deleted is to refetch the object URI, which should return either
# an error or a tombstone. This would allow us to verify that a deletion actually took
# place.
def handle_incoming( def handle_incoming(
%{"type" => "Delete", "object" => object_id, "actor" => actor, "id" => _id} = data %{"type" => "Delete", "object" => object_id, "actor" => _actor, "id" => _id} = data
) do ) do
object_id = Utils.get_ap_id(object_id) object_id = Utils.get_ap_id(object_id)
with actor <- get_actor(data), with actor <- get_actor(data),
%User{} = _actor <- User.get_or_fetch_by_ap_id(actor), %User{} = actor <- User.get_or_fetch_by_ap_id(actor),
{:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id), {:ok, object} <- get_obj_helper(object_id) || fetch_obj_helper(object_id),
:ok <- contain_origin(actor.ap_id, object.data),
{:ok, activity} <- ActivityPub.delete(object, false) do {:ok, activity} <- ActivityPub.delete(object, false) do
{:ok, activity} {:ok, activity}
else else
......
...@@ -361,6 +361,26 @@ test "it works for incoming deletes" do ...@@ -361,6 +361,26 @@ test "it works for incoming deletes" do
refute Repo.get(Activity, activity.id) refute Repo.get(Activity, activity.id)
end end
test "it fails for incoming deletes with spoofed origin" do
activity = insert(:note_activity)
data =
File.read!("test/fixtures/mastodon-delete.json")
|> Poison.decode!()
object =
data["object"]
|> Map.put("id", activity.data["object"]["id"])
data =
data
|> Map.put("object", object)
:error = Transmogrifier.handle_incoming(data)
assert Repo.get(Activity, activity.id)
end
test "it works for incoming unannounces with an existing notice" do test "it works for incoming unannounces with an existing notice" do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment