ostatus: explicitly disallow protocol downgrade from activitypub
This closes embargoed bug #1135.
This commit is contained in:
parent
957de9d771
commit
f72e0b7cad
|
@ -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.
|
||||
|
||||
### Changed
|
||||
- **Breaking:** Configuration: A setting to explicitly disable the mailer was added, defaulting to true, if you are using a mailer add `config :pleroma, Pleroma.Emails.Mailer, enabled: true` to your config
|
||||
- **Breaking:** Configuration: `/media/` is now removed when `base_url` is configured, append `/media/` to your `base_url` config to keep the old behaviour if desired
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -111,7 +111,7 @@ def handle_note(entry, doc \\ nil, options \\ []) 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 @@ def remote_follow_path do
|
|||
|
||||
def handle_incoming(xml_string, options \\ []) 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)
|
||||
|
@ -120,7 +120,7 @@ def handle_incoming(xml_string, options \\ []) 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
|
||||
|
@ -138,7 +138,7 @@ def handle_share(entry, doc) 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
|
||||
|
@ -264,11 +264,18 @@ def maybe_update_ostatus(doc, user) 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
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ test "find_or_make_user sets all the nessary input fields" 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)
|
||||
|
@ -439,14 +439,56 @@ test "find_make_or_update_user takes an author element and returns an updated us
|
|||
|
||||
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…
Reference in a new issue