diff options
author | lain <lain@soykaf.club> | 2024-05-22 14:58:48 +0000 |
---|---|---|
committer | lain <lain@soykaf.club> | 2024-05-22 14:58:48 +0000 |
commit | a8e1fc0f6a1520d97d78e2d15d72b829b4450607 (patch) | |
tree | 31b1ab1f291ca9d721c0de581b33803d555686b3 /lib | |
parent | c8e5a1f6b04721ff965e79448a7bed460f26135f (diff) | |
parent | 5f1f574f01ea18170a228a8cb273e143d2f05ab4 (diff) | |
download | pleroma-a8e1fc0f6a1520d97d78e2d15d72b829b4450607.tar.gz pleroma-a8e1fc0f6a1520d97d78e2d15d72b829b4450607.zip |
Merge branch 'webfinger-validation' into 'develop'
Fix validate_webfinger when running a different domain for Webfinger
See merge request pleroma/pleroma!4116
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/application.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/web_finger.ex | 32 |
2 files changed, 25 insertions, 10 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 75154f94c..649bb11c8 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -162,7 +162,8 @@ defmodule Pleroma.Application do expiration: chat_message_id_idempotency_key_expiration(), limit: 500_000 ), - build_cachex("rel_me", limit: 2500) + build_cachex("rel_me", limit: 2500), + build_cachex("host_meta", default_ttl: :timer.minutes(120), limit: 5000) ] end diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index e149d9247..e653b3338 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -155,7 +155,16 @@ defmodule Pleroma.Web.WebFinger do end end + @cachex Pleroma.Config.get([:cachex, :provider], Cachex) def find_lrdd_template(domain) do + @cachex.fetch!(:host_meta_cache, domain, fn _ -> + {:commit, fetch_lrdd_template(domain)} + end) + rescue + e -> {:error, "Cachex error: #{inspect(e)}"} + end + + defp fetch_lrdd_template(domain) do # WebFinger is restricted to HTTPS - https://tools.ietf.org/html/rfc7033#section-9.1 meta_url = "https://#{domain}/.well-known/host-meta" @@ -168,7 +177,7 @@ defmodule Pleroma.Web.WebFinger do end end - defp get_address_from_domain(domain, encoded_account) when is_binary(domain) do + defp get_address_from_domain(domain, "acct:" <> _ = encoded_account) when is_binary(domain) do case find_lrdd_template(domain) do {:ok, template} -> String.replace(template, "{uri}", encoded_account) @@ -178,6 +187,11 @@ defmodule Pleroma.Web.WebFinger do end end + defp get_address_from_domain(domain, account) when is_binary(domain) do + encoded_account = URI.encode("acct:#{account}") + get_address_from_domain(domain, encoded_account) + end + defp get_address_from_domain(_, _), do: {:error, :webfinger_no_domain} @spec finger(String.t()) :: {:ok, map()} | {:error, any()} @@ -192,9 +206,7 @@ defmodule Pleroma.Web.WebFinger do URI.parse(account).host end - encoded_account = URI.encode("acct:#{account}") - - with address when is_binary(address) <- get_address_from_domain(domain, encoded_account), + with address when is_binary(address) <- get_address_from_domain(domain, account), {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- HTTP.get( address, @@ -227,13 +239,15 @@ defmodule Pleroma.Web.WebFinger do end end - defp validate_webfinger(url, %{"subject" => "acct:" <> acct} = data) do - with %URI{host: request_host} <- URI.parse(url), - [_name, acct_host] <- String.split(acct, "@"), - {_, true} <- {:hosts_match_or_subdomain, String.ends_with?(request_host, acct_host)} do + defp validate_webfinger(request_url, %{"subject" => "acct:" <> acct = subject} = data) do + with [_name, acct_host] <- String.split(acct, "@"), + {_, url} <- {:address, get_address_from_domain(acct_host, subject)}, + %URI{host: request_host} <- URI.parse(request_url), + %URI{host: acct_host} <- URI.parse(url), + {_, true} <- {:hosts_match, acct_host == request_host} do {:ok, data} else - _ -> {:error, {:webfinger_invalid, url, data}} + _ -> {:error, {:webfinger_invalid, request_url, data}} end end |