federation/in: improve reply on requests from blocked domains
All checks were successful
ci/woodpecker/pr/lint Pipeline was successful
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline was successful
ci/woodpecker/pr/build-arm64 Pipeline was successful
ci/woodpecker/pr/build-amd64 Pipeline was successful
ci/woodpecker/pr/docs Pipeline was successful
ci/woodpecker/pull_request_closed/lint Pipeline was successful
ci/woodpecker/pull_request_closed/test/2 Pipeline was successful
ci/woodpecker/pull_request_closed/test/1 Pipeline was successful
ci/woodpecker/pull_request_closed/build-arm64 Pipeline was successful
ci/woodpecker/pull_request_closed/build-amd64 Pipeline was successful
ci/woodpecker/pull_request_closed/docs Pipeline was successful

Previously all such requests led to '401 Unauthorized'
whih might have triggered retries.
Now, to not leak any MRF info, we just indicate an
accept for POST requests without actually processing the object
and indiscriminately return "not found" for GET requests.

Notably this change also now causes all signed fetch requests from
blocked domains to be rejected even if authorized_fetch isn’t enabled.

Fixes: #929
This commit is contained in:
Oneric 2025-06-08 14:01:27 +02:00
parent 42022d5f48
commit 0a9e7d4712
2 changed files with 35 additions and 13 deletions

View file

@ -95,6 +95,20 @@ defp maybe_halt(conn, :gone) do
end
end
defp maybe_halt(conn, {:reject, _}) do
cond do
conn.method == "POST" ->
conn
|> resp(202, "Accepted")
|> halt()
true ->
conn
|> resp(404, "Not found")
|> halt()
end
end
defp maybe_halt(conn, _), do: conn
defp assign_valid_signature(%{assigns: %{valid_signature: true}} = conn, _),

View file

@ -163,19 +163,27 @@ test "fails on gone key for non-Delete" do
assert conn.assigns.signature_user == nil
end
test "fails on rejected keys", %{user: user} do
conn =
build_conn(:post, "/inbox", %{"type" => "Note"})
|> put_format("activity+json")
|> assign(:rejected_key_id, true)
|> put_req_header(
"signature",
"keyId=\"#{user.signing_key.key_id}\""
)
|> HTTPSignaturePlug.call(%{})
test "fakes accept for POST on rejected keys", %{user: user} do
build_conn(:post, "/inbox", %{"type" => "Note"})
|> put_format("activity+json")
|> assign(:rejected_key_id, true)
|> put_req_header(
"signature",
"keyId=\"#{user.signing_key.key_id}\""
)
|> HTTPSignaturePlug.call(%{})
|> response(202)
end
refute conn.halted
assert conn.assigns.valid_signature == false
assert conn.assigns.signature_user == nil
test "fakes not found for GET on rejected keys", %{user: user} do
build_conn(:get, "/doesntmattter", %{"user" => user.ap_id})
|> put_format("activity+json")
|> assign(:rejected_key_id, true)
|> put_req_header(
"signature",
"keyId=\"#{user.signing_key.key_id}\""
)
|> HTTPSignaturePlug.call(%{})
|> response(404)
end
end