Merge branch 'webfinger-actual-fix' into 'develop'

Fix WebFinger for split-domain setups

See merge request pleroma/pleroma!4405
This commit is contained in:
lain 2025-12-22 07:38:55 +00:00
commit d19b992417
4 changed files with 142 additions and 32 deletions

View file

@ -93,7 +93,7 @@ defmodule Pleroma.Web.WebFingerTest do
{:ok, _data} = WebFinger.finger(user)
end
test "it work for AP-only user" do
test "it works for AP-only user" do
user = "kpherox@mstdn.jp"
{:ok, data} = WebFinger.finger(user)
@ -224,24 +224,84 @@ defmodule Pleroma.Web.WebFingerTest do
status: 200,
body: File.read!("test/fixtures/tesla_mock/gleasonator.com_host_meta")
}}
%{url: "https://whitehouse.gov/.well-known/webfinger?resource=acct:trump@whitehouse.gov"} ->
{:ok, %Tesla.Env{status: 404}}
end)
{:error, _data} = WebFinger.finger("alex@gleasonator.com")
end
end
test "prevents forgeries" do
Tesla.Mock.mock(fn
%{url: "https://fba.ryona.agency/.well-known/webfinger?resource=acct:graf@fba.ryona.agency"} ->
fake_webfinger =
File.read!("test/fixtures/webfinger/graf-imposter-webfinger.json") |> Jason.decode!()
test "prevents forgeries" do
Tesla.Mock.mock(fn
%{
url:
"https://fba.ryona.agency/.well-known/webfinger?resource=acct:graf@fba.ryona.agency"
} ->
fake_webfinger =
File.read!("test/fixtures/webfinger/graf-imposter-webfinger.json") |> Jason.decode!()
Tesla.Mock.json(fake_webfinger)
Tesla.Mock.json(fake_webfinger)
%{url: "https://fba.ryona.agency/.well-known/host-meta"} ->
{:ok, %Tesla.Env{status: 404}}
end)
%{url: url}
when url in [
"https://poa.st/.well-known/webfinger?resource=acct:graf@poa.st",
"https://fba.ryona.agency/.well-known/host-meta"
] ->
{:ok, %Tesla.Env{status: 404}}
end)
assert {:error, _} = WebFinger.finger("graf@fba.ryona.agency")
assert {:error, _} = WebFinger.finger("graf@fba.ryona.agency")
end
test "prevents forgeries even when the spoofed subject exists on the target domain" do
Tesla.Mock.mock(fn
%{url: url}
when url in [
"https://attacker.example/.well-known/host-meta",
"https://victim.example/.well-known/host-meta"
] ->
{:ok, %Tesla.Env{status: 404}}
%{
url:
"https://attacker.example/.well-known/webfinger?resource=acct:alice@attacker.example"
} ->
Tesla.Mock.json(%{
"subject" => "acct:alice@victim.example",
"links" => [
%{
"rel" => "self",
"type" => "application/activity+json",
"href" => "https://attacker.example/users/alice"
}
]
})
%{url: "https://victim.example/.well-known/webfinger?resource=acct:alice@victim.example"} ->
Tesla.Mock.json(%{
"subject" => "acct:alice@victim.example",
"links" => [
%{
"rel" => "self",
"type" => "application/activity+json",
"href" => "https://victim.example/users/alice"
}
]
})
end)
assert {:error, _} = WebFinger.finger("alice@attacker.example")
end
test "works for correctly set up split-domain instances implementing host-meta redirect" do
{:ok, _data} = WebFinger.finger("a@pleroma.example")
{:ok, _data} = WebFinger.finger("a@sub.pleroma.example")
end
test "works for correctly set up split-domain instances without host-meta redirect" do
{:ok, _data} = WebFinger.finger("a@mastodon.example")
{:ok, _data} = WebFinger.finger("a@sub.mastodon.example")
end
end
end

View file

@ -1229,7 +1229,8 @@ defmodule HttpRequestMock do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def get("https://mstdn.jp/.well-known/webfinger?resource=acct:kpherox@mstdn.jp", _, _, _) do
def get("https://mstdn.jp/.well-known/webfinger?resource=acct:" <> acct, _, _, _)
when acct in ["kpherox@mstdn.jp", "kPherox@mstdn.jp"] do
{:ok,
%Tesla.Env{
status: 200,
@ -1526,14 +1527,6 @@ defmodule HttpRequestMock do
}}
end
def get("https://mastodon.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
status: 302,
headers: [{"location", "https://sub.mastodon.example/.well-known/host-meta"}]
}}
end
def get("https://sub.mastodon.example/.well-known/host-meta", _, _, _) do
{:ok,
%Tesla.Env{
@ -1546,11 +1539,15 @@ defmodule HttpRequestMock do
end
def get(
"https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example",
url,
_,
_,
_
) do
)
when url in [
"https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example",
"https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@sub.mastodon.example"
] do
{:ok,
%Tesla.Env{
status: 200,
@ -1564,6 +1561,22 @@ defmodule HttpRequestMock do
}}
end
def get(
"https://mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example",
_,
_,
_
) do
{:ok,
%Tesla.Env{
status: 302,
headers: [
{"location",
"https://sub.mastodon.example/.well-known/webfinger?resource=acct:a@mastodon.example"}
]
}}
end
def get("https://sub.mastodon.example/users/a", _, _, _) do
{:ok,
%Tesla.Env{
@ -1609,11 +1622,15 @@ defmodule HttpRequestMock do
end
def get(
"https://sub.pleroma.example/.well-known/webfinger?resource=acct:a@pleroma.example",
url,
_,
_,
_
) do
)
when url in [
"https://sub.pleroma.example/.well-known/webfinger?resource=acct:a@pleroma.example",
"https://sub.pleroma.example/.well-known/webfinger?resource=acct:a@sub.pleroma.example"
] do
{:ok,
%Tesla.Env{
status: 200,