Never fetch resource from ourselves

If it’s not already in the database,
it must be counterfeit (or just not exists at all)

Changed test URLs were only ever used from "local: false" users anyway.
This commit is contained in:
Oneric 2024-03-13 21:00:23 -01:00
parent fee57eb376
commit 59a142e0b0
14 changed files with 77 additions and 53 deletions

View File

@ -47,6 +47,19 @@ defmodule Pleroma.Object.Containment do
defp compare_uris(%URI{host: host} = _id_uri, %URI{host: host} = _other_uri), do: :ok defp compare_uris(%URI{host: host} = _id_uri, %URI{host: host} = _other_uri), do: :ok
defp compare_uris(_id_uri, _other_uri), do: :error defp compare_uris(_id_uri, _other_uri), do: :error
@doc """
Checks whether an URL to fetch from is from the local server.
We never want to fetch from ourselves; if its not in the database
it cant be authentic and must be a counterfeit.
"""
def contain_local_fetch(id) do
case compare_uris(URI.parse(id), Pleroma.Web.Endpoint.struct_url()) do
:ok -> :error
_ -> :ok
end
end
@doc """ @doc """
Checks that an imported AP object's actor matches the host it came from. Checks that an imported AP object's actor matches the host it came from.
""" """

View File

@ -258,6 +258,7 @@ defmodule Pleroma.Object.Fetcher do
Logger.debug("Fetching object #{id} via AP") Logger.debug("Fetching object #{id} via AP")
with {:scheme, true} <- {:scheme, String.starts_with?(id, "http")}, with {:scheme, true} <- {:scheme, String.starts_with?(id, "http")},
{_, :ok} <- {:local_fetch, Containment.contain_local_fetch(id)},
{:ok, body} <- get_object(id), {:ok, body} <- get_object(id),
{:ok, data} <- safe_json_decode(body), {:ok, data} <- safe_json_decode(body),
{_, :ok} <- {:containment, Containment.contain_origin_from_id(id, data)}, {_, :ok} <- {:containment, Containment.contain_origin_from_id(id, data)},
@ -271,6 +272,9 @@ defmodule Pleroma.Object.Fetcher do
{:scheme, _} -> {:scheme, _} ->
{:error, "Unsupported URI scheme"} {:error, "Unsupported URI scheme"}
{:local_fetch, _} ->
{:error, "Trying to fetch local resource"}
{:containment, _} -> {:containment, _} ->
{:error, "Object containment failed."} {:error, "Object containment failed."}

View File

@ -13,7 +13,7 @@
"directMessage": "litepub:directMessage" "directMessage": "litepub:directMessage"
} }
], ],
"id": "http://localhost:8080/followers/fuser3", "id": "http://remote.org/followers/fuser3",
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 296 "totalItems": 296
} }

View File

@ -13,7 +13,7 @@
"directMessage": "litepub:directMessage" "directMessage": "litepub:directMessage"
} }
], ],
"id": "http://localhost:8080/following/fuser3", "id": "http://remote.org/following/fuser3",
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 32 "totalItems": 32
} }

View File

@ -1,7 +1,7 @@
{ {
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
"id": "http://localhost:4001/users/masto_closed/followers", "id": "http://remote.org/users/masto_closed/followers",
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 437, "totalItems": 437,
"first": "http://localhost:4001/users/masto_closed/followers?page=1" "first": "http://remote.org/users/masto_closed/followers?page=1"
} }

View File

@ -1 +1 @@
{"@context":"https://www.w3.org/ns/activitystreams","id":"http://localhost:4001/users/masto_closed/followers?page=1","type":"OrderedCollectionPage","totalItems":437,"next":"http://localhost:4001/users/masto_closed/followers?page=2","partOf":"http://localhost:4001/users/masto_closed/followers","orderedItems":["https://testing.uguu.ltd/users/rin","https://patch.cx/users/rin","https://letsalllovela.in/users/xoxo","https://pleroma.site/users/crushv","https://aria.company/users/boris","https://kawen.space/users/crushv","https://freespeech.host/users/cvcvcv","https://pleroma.site/users/picpub","https://pixelfed.social/users/nosleep","https://boopsnoot.gq/users/5c1896d162f7d337f90492a3","https://pikachu.rocks/users/waifu","https://royal.crablettesare.life/users/crablettes"]} {"@context":"https://www.w3.org/ns/activitystreams","id":"http://remote.org/users/masto_closed/followers?page=1","type":"OrderedCollectionPage","totalItems":437,"next":"http://remote.org/users/masto_closed/followers?page=2","partOf":"http://remote.org/users/masto_closed/followers","orderedItems":["https://testing.uguu.ltd/users/rin","https://patch.cx/users/rin","https://letsalllovela.in/users/xoxo","https://pleroma.site/users/crushv","https://aria.company/users/boris","https://kawen.space/users/crushv","https://freespeech.host/users/cvcvcv","https://pleroma.site/users/picpub","https://pixelfed.social/users/nosleep","https://boopsnoot.gq/users/5c1896d162f7d337f90492a3","https://pikachu.rocks/users/waifu","https://royal.crablettesare.life/users/crablettes"]}

View File

@ -1,7 +1,7 @@
{ {
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
"id": "http://localhost:4001/users/masto_closed/following", "id": "http://remote.org/users/masto_closed/following",
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 152, "totalItems": 152,
"first": "http://localhost:4001/users/masto_closed/following?page=1" "first": "http://remote.org/users/masto_closed/following?page=1"
} }

View File

@ -1 +1 @@
{"@context":"https://www.w3.org/ns/activitystreams","id":"http://localhost:4001/users/masto_closed/following?page=1","type":"OrderedCollectionPage","totalItems":152,"next":"http://localhost:4001/users/masto_closed/following?page=2","partOf":"http://localhost:4001/users/masto_closed/following","orderedItems":["https://testing.uguu.ltd/users/rin","https://patch.cx/users/rin","https://letsalllovela.in/users/xoxo","https://pleroma.site/users/crushv","https://aria.company/users/boris","https://kawen.space/users/crushv","https://freespeech.host/users/cvcvcv","https://pleroma.site/users/picpub","https://pixelfed.social/users/nosleep","https://boopsnoot.gq/users/5c1896d162f7d337f90492a3","https://pikachu.rocks/users/waifu","https://royal.crablettesare.life/users/crablettes"]} {"@context":"https://www.w3.org/ns/activitystreams","id":"http://remote.org/users/masto_closed/following?page=1","type":"OrderedCollectionPage","totalItems":152,"next":"http://remote.org/users/masto_closed/following?page=2","partOf":"http://remote.org/users/masto_closed/following","orderedItems":["https://testing.uguu.ltd/users/rin","https://patch.cx/users/rin","https://letsalllovela.in/users/xoxo","https://pleroma.site/users/crushv","https://aria.company/users/boris","https://kawen.space/users/crushv","https://freespeech.host/users/cvcvcv","https://pleroma.site/users/picpub","https://pixelfed.social/users/nosleep","https://boopsnoot.gq/users/5c1896d162f7d337f90492a3","https://pikachu.rocks/users/waifu","https://royal.crablettesare.life/users/crablettes"]}

View File

@ -1,14 +1,14 @@
{ {
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 527, "totalItems": 527,
"id": "http://localhost:4001/users/fuser2/followers", "id": "http://remote.org/users/fuser2/followers",
"first": { "first": {
"type": "OrderedCollectionPage", "type": "OrderedCollectionPage",
"totalItems": 527, "totalItems": 527,
"partOf": "http://localhost:4001/users/fuser2/followers", "partOf": "http://remote.org/users/fuser2/followers",
"orderedItems": [], "orderedItems": [],
"next": "http://localhost:4001/users/fuser2/followers?page=2", "next": "http://remote.org/users/fuser2/followers?page=2",
"id": "http://localhost:4001/users/fuser2/followers?page=1" "id": "http://remote.org/users/fuser2/followers?page=1"
}, },
"@context": [ "@context": [
"https://www.w3.org/ns/activitystreams", "https://www.w3.org/ns/activitystreams",

View File

@ -1,14 +1,14 @@
{ {
"type": "OrderedCollection", "type": "OrderedCollection",
"totalItems": 267, "totalItems": 267,
"id": "http://localhost:4001/users/fuser2/following", "id": "http://remote.org/users/fuser2/following",
"first": { "first": {
"type": "OrderedCollectionPage", "type": "OrderedCollectionPage",
"totalItems": 267, "totalItems": 267,
"partOf": "http://localhost:4001/users/fuser2/following", "partOf": "http://remote.org/users/fuser2/following",
"orderedItems": [], "orderedItems": [],
"next": "http://localhost:4001/users/fuser2/following?page=2", "next": "http://remote.org/users/fuser2/following?page=2",
"id": "http://localhost:4001/users/fuser2/following?page=1" "id": "http://remote.org/users/fuser2/following?page=1"
}, },
"@context": [ "@context": [
"https://www.w3.org/ns/activitystreams", "https://www.w3.org/ns/activitystreams",

View File

@ -237,6 +237,13 @@ defmodule Pleroma.Object.FetcherTest do
"https://patch.cx/objects/spoof_foreign_actor" "https://patch.cx/objects/spoof_foreign_actor"
) )
end end
test "it does not fetch from localhost" do
assert {:error, "Trying to fetch local resource"} =
Fetcher.fetch_and_contain_remote_object_from_id(
Pleroma.Web.Endpoint.url() <> "/spoof_local"
)
end
end end
describe "fetching an object" do describe "fetching an object" do

View File

@ -326,9 +326,9 @@ defmodule Pleroma.UserTest do
insert(:user, %{ insert(:user, %{
local: false, local: false,
nickname: "fuser2", nickname: "fuser2",
ap_id: "http://localhost:4001/users/fuser2", ap_id: "http://remote.org/users/fuser2",
follower_address: "http://localhost:4001/users/fuser2/followers", follower_address: "http://remote.org/users/fuser2/followers",
following_address: "http://localhost:4001/users/fuser2/following" following_address: "http://remote.org/users/fuser2/following"
}) })
{:ok, user, followed} = User.follow(user, followed, :follow_accept) {:ok, user, followed} = User.follow(user, followed, :follow_accept)
@ -2177,8 +2177,8 @@ defmodule Pleroma.UserTest do
describe "sync followers count" do describe "sync followers count" do
setup do setup do
user1 = insert(:user, local: false, ap_id: "http://localhost:4001/users/masto_closed") user1 = insert(:user, local: false, ap_id: "http://remote.org/users/masto_closed")
user2 = insert(:user, local: false, ap_id: "http://localhost:4001/users/fuser2") user2 = insert(:user, local: false, ap_id: "http://remote.org/users/fuser2")
insert(:user, local: true) insert(:user, local: true)
insert(:user, local: false, is_active: false) insert(:user, local: false, is_active: false)
{:ok, user1: user1, user2: user2} {:ok, user1: user1, user2: user2}
@ -2272,8 +2272,8 @@ defmodule Pleroma.UserTest do
other_user = other_user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers", follower_address: "http://remote.org/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following", following_address: "http://remote.org/users/masto_closed/following",
ap_enabled: true ap_enabled: true
) )
@ -2294,8 +2294,8 @@ defmodule Pleroma.UserTest do
other_user = other_user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers", follower_address: "http://remote.org/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following", following_address: "http://remote.org/users/masto_closed/following",
ap_enabled: true ap_enabled: true
) )
@ -2316,8 +2316,8 @@ defmodule Pleroma.UserTest do
other_user = other_user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers", follower_address: "http://remote.org/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following", following_address: "http://remote.org/users/masto_closed/following",
ap_enabled: true ap_enabled: true
) )

View File

@ -1643,8 +1643,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/fuser2/followers", follower_address: "http://remote.org/users/fuser2/followers",
following_address: "http://localhost:4001/users/fuser2/following" following_address: "http://remote.org/users/fuser2/following"
) )
{:ok, info} = ActivityPub.fetch_follow_information_for_user(user) {:ok, info} = ActivityPub.fetch_follow_information_for_user(user)
@ -1655,7 +1655,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "detects hidden followers" do test "detects hidden followers" do
mock(fn env -> mock(fn env ->
case env.url do case env.url do
"http://localhost:4001/users/masto_closed/followers?page=1" -> "http://remote.org/users/masto_closed/followers?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
_ -> _ ->
@ -1666,8 +1666,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers", follower_address: "http://remote.org/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following" following_address: "http://remote.org/users/masto_closed/following"
) )
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
@ -1678,7 +1678,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "detects hidden follows" do test "detects hidden follows" do
mock(fn env -> mock(fn env ->
case env.url do case env.url do
"http://localhost:4001/users/masto_closed/following?page=1" -> "http://remote.org/users/masto_closed/following?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
_ -> _ ->
@ -1689,8 +1689,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers", follower_address: "http://remote.org/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following" following_address: "http://remote.org/users/masto_closed/following"
) )
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
@ -1702,8 +1702,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:8080/followers/fuser3", follower_address: "http://remote.org/followers/fuser3",
following_address: "http://localhost:8080/following/fuser3" following_address: "http://remote.org/following/fuser3"
) )
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)
@ -1716,28 +1716,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "doesn't crash when follower and following counters are hidden" do test "doesn't crash when follower and following counters are hidden" do
mock(fn env -> mock(fn env ->
case env.url do case env.url do
"http://localhost:4001/users/masto_hidden_counters/following" -> "http://remote.org/users/masto_hidden_counters/following" ->
json( json(
%{ %{
"@context" => "https://www.w3.org/ns/activitystreams", "@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/followers" "id" => "http://remote.org/users/masto_hidden_counters/followers"
}, },
headers: HttpRequestMock.activitypub_object_headers() headers: HttpRequestMock.activitypub_object_headers()
) )
"http://localhost:4001/users/masto_hidden_counters/following?page=1" -> "http://remote.org/users/masto_hidden_counters/following?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
"http://localhost:4001/users/masto_hidden_counters/followers" -> "http://remote.org/users/masto_hidden_counters/followers" ->
json( json(
%{ %{
"@context" => "https://www.w3.org/ns/activitystreams", "@context" => "https://www.w3.org/ns/activitystreams",
"id" => "http://localhost:4001/users/masto_hidden_counters/following" "id" => "http://remote.org/users/masto_hidden_counters/following"
}, },
headers: HttpRequestMock.activitypub_object_headers() headers: HttpRequestMock.activitypub_object_headers()
) )
"http://localhost:4001/users/masto_hidden_counters/followers?page=1" -> "http://remote.org/users/masto_hidden_counters/followers?page=1" ->
%Tesla.Env{status: 403, body: ""} %Tesla.Env{status: 403, body: ""}
end end
end) end)
@ -1745,8 +1745,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = user =
insert(:user, insert(:user,
local: false, local: false,
follower_address: "http://localhost:4001/users/masto_hidden_counters/followers", follower_address: "http://remote.org/users/masto_hidden_counters/followers",
following_address: "http://localhost:4001/users/masto_hidden_counters/following" following_address: "http://remote.org/users/masto_hidden_counters/following"
) )
{:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user)

View File

@ -964,7 +964,7 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}} {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}
end end
def get("http://localhost:4001/users/masto_closed/followers", _, _, _) do def get("http://remote.org/users/masto_closed/followers", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -973,7 +973,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:4001/users/masto_closed/followers?page=1", _, _, _) do def get("http://remote.org/users/masto_closed/followers?page=1", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -982,7 +982,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:4001/users/masto_closed/following", _, _, _) do def get("http://remote.org/users/masto_closed/following", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -991,7 +991,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:4001/users/masto_closed/following?page=1", _, _, _) do def get("http://remote.org/users/masto_closed/following?page=1", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -1000,7 +1000,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:8080/followers/fuser3", _, _, _) do def get("http://remote.org/followers/fuser3", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -1009,7 +1009,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:8080/following/fuser3", _, _, _) do def get("http://remote.org/following/fuser3", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -1018,7 +1018,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:4001/users/fuser2/followers", _, _, _) do def get("http://remote.org/users/fuser2/followers", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,
@ -1027,7 +1027,7 @@ defmodule HttpRequestMock do
}} }}
end end
def get("http://localhost:4001/users/fuser2/following", _, _, _) do def get("http://remote.org/users/fuser2/following", _, _, _) do
{:ok, {:ok,
%Tesla.Env{ %Tesla.Env{
status: 200, status: 200,