mirror of
https://git.pleroma.social/pleroma/pleroma.git
synced 2025-04-24 22:07:52 -04:00
ostatus: explicitly disallow protocol downgrade from activitypub
This closes embargoed bug #1135.
This commit is contained in:
parent
cca9d64cb8
commit
59e60c6db1
6 changed files with 63 additions and 11 deletions
|
@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [Unreleased]
|
||||
### Security
|
||||
- OStatus: eliminate the possibility of a protocol downgrade attack.
|
||||
|
||||
### Fixed
|
||||
- `pleroma_ctl` not detecting the master branch properly. If you get "Releases are built only for master and develop branches" error when updating, please add `-` to the end of the line in `releases/start_erl.data`
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.OStatus.FollowHandler do
|
|||
alias Pleroma.Web.XML
|
||||
|
||||
def handle(entry, doc) do
|
||||
with {:ok, actor} <- OStatus.find_make_or_update_user(doc),
|
||||
with {:ok, actor} <- OStatus.find_make_or_update_actor(doc),
|
||||
id when not is_nil(id) <- XML.string_from_xpath("/entry/id", entry),
|
||||
followed_uri when not is_nil(followed_uri) <-
|
||||
XML.string_from_xpath("/entry/activity:object/id", entry),
|
||||
|
|
|
@ -108,7 +108,7 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
|
|||
with id <- XML.string_from_xpath("//id", entry),
|
||||
activity when is_nil(activity) <- Activity.get_create_by_object_ap_id_with_object(id),
|
||||
[author] <- :xmerl_xpath.string('//author[1]', doc),
|
||||
{:ok, actor} <- OStatus.find_make_or_update_user(author),
|
||||
{:ok, actor} <- OStatus.find_make_or_update_actor(author),
|
||||
content_html <- OStatus.get_content(entry),
|
||||
cw <- OStatus.get_cw(entry),
|
||||
in_reply_to <- XML.string_from_xpath("//thr:in-reply-to[1]/@ref", entry),
|
||||
|
|
|
@ -9,7 +9,7 @@ defmodule Pleroma.Web.OStatus.UnfollowHandler do
|
|||
alias Pleroma.Web.XML
|
||||
|
||||
def handle(entry, doc) do
|
||||
with {:ok, actor} <- OStatus.find_make_or_update_user(doc),
|
||||
with {:ok, actor} <- OStatus.find_make_or_update_actor(doc),
|
||||
id when not is_nil(id) <- XML.string_from_xpath("/entry/id", entry),
|
||||
followed_uri when not is_nil(followed_uri) <-
|
||||
XML.string_from_xpath("/entry/activity:object/id", entry),
|
||||
|
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Web.OStatus do
|
|||
|
||||
def handle_incoming(xml_string) do
|
||||
with doc when doc != :error <- parse_document(xml_string) do
|
||||
with {:ok, actor_user} <- find_make_or_update_user(doc),
|
||||
with {:ok, actor_user} <- find_make_or_update_actor(doc),
|
||||
do: Pleroma.Instances.set_reachable(actor_user.ap_id)
|
||||
|
||||
entries = :xmerl_xpath.string('//entry', doc)
|
||||
|
@ -118,7 +118,7 @@ defmodule Pleroma.Web.OStatus do
|
|||
end
|
||||
|
||||
def make_share(entry, doc, retweeted_activity) do
|
||||
with {:ok, actor} <- find_make_or_update_user(doc),
|
||||
with {:ok, actor} <- find_make_or_update_actor(doc),
|
||||
%Object{} = object <- Object.normalize(retweeted_activity),
|
||||
id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
|
||||
{:ok, activity, _object} = ActivityPub.announce(actor, object, id, false) do
|
||||
|
@ -136,7 +136,7 @@ defmodule Pleroma.Web.OStatus do
|
|||
end
|
||||
|
||||
def make_favorite(entry, doc, favorited_activity) do
|
||||
with {:ok, actor} <- find_make_or_update_user(doc),
|
||||
with {:ok, actor} <- find_make_or_update_actor(doc),
|
||||
%Object{} = object <- Object.normalize(favorited_activity),
|
||||
id when not is_nil(id) <- string_from_xpath("/entry/id", entry),
|
||||
{:ok, activity, _object} = ActivityPub.like(actor, object, id, false) do
|
||||
|
@ -262,11 +262,18 @@ defmodule Pleroma.Web.OStatus do
|
|||
end
|
||||
end
|
||||
|
||||
def find_make_or_update_user(doc) do
|
||||
def find_make_or_update_actor(doc) do
|
||||
uri = string_from_xpath("//author/uri[1]", doc)
|
||||
|
||||
with {:ok, user} <- find_or_make_user(uri) do
|
||||
with {:ok, %User{} = user} <- find_or_make_user(uri),
|
||||
{:ap_enabled, false} <- {:ap_enabled, User.ap_enabled?(user)} do
|
||||
maybe_update(doc, user)
|
||||
else
|
||||
{:ap_enabled, true} ->
|
||||
{:error, :invalid_protocol}
|
||||
|
||||
_ ->
|
||||
{:error, :unknown_user}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -401,7 +401,7 @@ defmodule Pleroma.Web.OStatusTest do
|
|||
}
|
||||
end
|
||||
|
||||
test "find_make_or_update_user takes an author element and returns an updated user" do
|
||||
test "find_make_or_update_actor takes an author element and returns an updated user" do
|
||||
uri = "https://social.heldscal.la/user/23211"
|
||||
|
||||
{:ok, user} = OStatus.find_or_make_user(uri)
|
||||
|
@ -414,14 +414,56 @@ defmodule Pleroma.Web.OStatusTest do
|
|||
|
||||
doc = XML.parse_document(File.read!("test/fixtures/23211.atom"))
|
||||
[author] = :xmerl_xpath.string('//author[1]', doc)
|
||||
{:ok, user} = OStatus.find_make_or_update_user(author)
|
||||
{:ok, user} = OStatus.find_make_or_update_actor(author)
|
||||
assert user.avatar["type"] == "Image"
|
||||
assert user.name == old_name
|
||||
assert user.bio == old_bio
|
||||
|
||||
{:ok, user_again} = OStatus.find_make_or_update_user(author)
|
||||
{:ok, user_again} = OStatus.find_make_or_update_actor(author)
|
||||
assert user_again == user
|
||||
end
|
||||
|
||||
test "find_or_make_user disallows protocol downgrade" do
|
||||
user = insert(:user, %{local: true})
|
||||
{:ok, user} = OStatus.find_or_make_user(user.ap_id)
|
||||
|
||||
assert User.ap_enabled?(user)
|
||||
|
||||
user =
|
||||
insert(:user, %{
|
||||
ap_id: "https://social.heldscal.la/user/23211",
|
||||
info: %{ap_enabled: true},
|
||||
local: false
|
||||
})
|
||||
|
||||
assert User.ap_enabled?(user)
|
||||
|
||||
{:ok, user} = OStatus.find_or_make_user(user.ap_id)
|
||||
assert User.ap_enabled?(user)
|
||||
end
|
||||
|
||||
test "find_make_or_update_actor disallows protocol downgrade" do
|
||||
user = insert(:user, %{local: true})
|
||||
{:ok, user} = OStatus.find_or_make_user(user.ap_id)
|
||||
|
||||
assert User.ap_enabled?(user)
|
||||
|
||||
user =
|
||||
insert(:user, %{
|
||||
ap_id: "https://social.heldscal.la/user/23211",
|
||||
info: %{ap_enabled: true},
|
||||
local: false
|
||||
})
|
||||
|
||||
assert User.ap_enabled?(user)
|
||||
|
||||
{:ok, user} = OStatus.find_or_make_user(user.ap_id)
|
||||
assert User.ap_enabled?(user)
|
||||
|
||||
doc = XML.parse_document(File.read!("test/fixtures/23211.atom"))
|
||||
[author] = :xmerl_xpath.string('//author[1]', doc)
|
||||
{:error, :invalid_protocol} = OStatus.find_make_or_update_actor(author)
|
||||
end
|
||||
end
|
||||
|
||||
describe "gathering user info from a user id" do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue