diff --git a/changelog.d/webfinger-resolution.fix b/changelog.d/webfinger-resolution.fix new file mode 100644 index 000000000..71b927bb0 --- /dev/null +++ b/changelog.d/webfinger-resolution.fix @@ -0,0 +1 @@ +Enforce an exact domain match for WebFinger resolution diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index e653b3338..a53d58caa 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -35,9 +35,9 @@ defmodule Pleroma.Web.WebFinger do regex = if webfinger_domain = Pleroma.Config.get([__MODULE__, :domain]) do - ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@(#{host}|#{webfinger_domain})/ + ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@(#{host}|#{webfinger_domain})$/ else - ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@#{host}/ + ~r/(acct:)?(?[a-z0-9A-Z_\.-]+)@#{host}$/ end with %{"username" => username} <- Regex.named_captures(regex, resource), diff --git a/test/pleroma/web/web_finger/web_finger_controller_test.exs b/test/pleroma/web/web_finger/web_finger_controller_test.exs index be44e3a8b..ef52a4b85 100644 --- a/test/pleroma/web/web_finger/web_finger_controller_test.exs +++ b/test/pleroma/web/web_finger/web_finger_controller_test.exs @@ -33,47 +33,122 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do assert match?(^response_xml, expected_xml) end - test "Webfinger JRD" do - user = - insert(:user, - ap_id: "https://hyrule.world/users/zelda", - also_known_as: ["https://mushroom.kingdom/users/toad"] - ) + describe "Webfinger" do + test "JRD" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") - response = - build_conn() - |> put_req_header("accept", "application/jrd+json") - |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") - |> json_response(200) + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda" + ) - assert response["subject"] == "acct:#{user.nickname}@localhost" + response = + build_conn() + |> put_req_header("accept", "application/jrd+json") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@hyrule.world") + |> json_response(200) - assert response["aliases"] == [ - "https://hyrule.world/users/zelda", - "https://mushroom.kingdom/users/toad" - ] + assert response["subject"] == "acct:#{user.nickname}@hyrule.world" + + assert response["aliases"] == [ + "https://hyrule.world/users/zelda" + ] + end + + test "XML" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") + + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda" + ) + + response = + build_conn() + |> put_req_header("accept", "application/xrd+xml") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> response(200) + + assert response =~ "https://hyrule.world/users/zelda" + end end test "Webfinger defaults to JSON when no Accept header is provided" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") + user = insert(:user, - ap_id: "https://hyrule.world/users/zelda", - also_known_as: ["https://mushroom.kingdom/users/toad"] + ap_id: "https://hyrule.world/users/zelda" ) response = build_conn() - |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@hyrule.world") |> json_response(200) - assert response["subject"] == "acct:#{user.nickname}@localhost" + assert response["subject"] == "acct:#{user.nickname}@hyrule.world" assert response["aliases"] == [ - "https://hyrule.world/users/zelda", - "https://mushroom.kingdom/users/toad" + "https://hyrule.world/users/zelda" ] end + describe "Webfinger returns also_known_as / aliases in the response" do + test "JSON" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") + + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda", + also_known_as: [ + "https://mushroom.kingdom/users/toad", + "https://luigi.mansion/users/kingboo" + ] + ) + + response = + build_conn() + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@hyrule.world") + |> json_response(200) + + assert response["subject"] == "acct:#{user.nickname}@hyrule.world" + + assert response["aliases"] == [ + "https://hyrule.world/users/zelda", + "https://mushroom.kingdom/users/toad", + "https://luigi.mansion/users/kingboo" + ] + end + + test "XML" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") + + user = + insert(:user, + ap_id: "https://hyrule.world/users/zelda", + also_known_as: [ + "https://mushroom.kingdom/users/toad", + "https://luigi.mansion/users/kingboo" + ] + ) + + response = + build_conn() + |> put_req_header("accept", "application/xrd+xml") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> response(200) + + assert response =~ "https://hyrule.world/users/zelda" + assert response =~ "https://mushroom.kingdom/users/toad" + assert response =~ "https://luigi.mansion/users/kingboo" + end + end + test "reach user on tld, while pleroma is running on subdomain" do clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com") @@ -91,44 +166,32 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do assert response["aliases"] == ["https://sub.example.com/users/#{user.nickname}"] end - test "it returns 404 when user isn't found (JSON)" do - result = - build_conn() - |> put_req_header("accept", "application/jrd+json") - |> get("/.well-known/webfinger?resource=acct:jimm@localhost") - |> json_response(404) + describe "it returns 404 when user isn't found" do + test "JSON" do + result = + build_conn() + |> put_req_header("accept", "application/jrd+json") + |> get("/.well-known/webfinger?resource=acct:jimm@localhost") + |> json_response(404) - assert result == "Couldn't find user" - end + assert result == "Couldn't find user" + end - test "Webfinger XML" do - user = - insert(:user, - ap_id: "https://hyrule.world/users/zelda", - also_known_as: ["https://mushroom.kingdom/users/toad"] - ) + test "XML" do + result = + build_conn() + |> put_req_header("accept", "application/xrd+xml") + |> get("/.well-known/webfinger?resource=acct:jimm@localhost") + |> response(404) - response = - build_conn() - |> put_req_header("accept", "application/xrd+xml") - |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") - |> response(200) - - assert response =~ "https://hyrule.world/users/zelda" - assert response =~ "https://mushroom.kingdom/users/toad" - end - - test "it returns 404 when user isn't found (XML)" do - result = - build_conn() - |> put_req_header("accept", "application/xrd+xml") - |> get("/.well-known/webfinger?resource=acct:jimm@localhost") - |> response(404) - - assert result == "Couldn't find user" + assert result == "Couldn't find user" + end end test "Returns JSON when format is not supported" do + clear_config([Pleroma.Web.Endpoint, :url, :host], "hyrule.world") + clear_config([Pleroma.Web.WebFinger, :domain], "hyrule.world") + user = insert(:user, ap_id: "https://hyrule.world/users/zelda", @@ -138,10 +201,10 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do response = build_conn() |> put_req_header("accept", "text/html") - |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") + |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@hyrule.world") |> json_response(200) - assert response["subject"] == "acct:#{user.nickname}@localhost" + assert response["subject"] == "acct:#{user.nickname}@hyrule.world" assert response["aliases"] == [ "https://hyrule.world/users/zelda", diff --git a/test/pleroma/web/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs index aefe7b0c2..923074ed5 100644 --- a/test/pleroma/web/web_finger_test.exs +++ b/test/pleroma/web/web_finger_test.exs @@ -39,6 +39,23 @@ defmodule Pleroma.Web.WebFingerTest do end end + test "requires exact match for Endpoint host or WebFinger domain" do + clear_config([Pleroma.Web.WebFinger, :domain], "pleroma.dev") + user = insert(:user) + + assert {:error, "Couldn't find user"} == + WebFinger.webfinger("#{user.nickname}@#{Pleroma.Web.Endpoint.host()}xxxx", "JSON") + + assert {:error, "Couldn't find user"} == + WebFinger.webfinger("#{user.nickname}@pleroma.devxxxx", "JSON") + + assert {:ok, _} = + WebFinger.webfinger("#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", "JSON") + + assert {:ok, _} = + WebFinger.webfinger("#{user.nickname}@pleroma.dev", "JSON") + end + describe "fingering" do test "returns error for nonsensical input" do assert {:error, _} = WebFinger.finger("bliblablu")