Merge branch 'fix-webfinger-spoofing' into 'develop'
Fix webfinger spoofing See merge request pleroma/pleroma!4114
This commit is contained in:
commit
c8e5a1f6b0
1
changelog.d/fix-webfinger-spoofing.security
Normal file
1
changelog.d/fix-webfinger-spoofing.security
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix webfinger spoofing.
|
@ -216,10 +216,26 @@ defmodule Pleroma.Web.WebFinger do
|
|||||||
_ ->
|
_ ->
|
||||||
{:error, {:content_type, nil}}
|
{:error, {:content_type, nil}}
|
||||||
end
|
end
|
||||||
|
|> case do
|
||||||
|
{:ok, data} -> validate_webfinger(address, data)
|
||||||
|
error -> error
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error ->
|
error ->
|
||||||
Logger.debug("Couldn't finger #{account}: #{inspect(error)}")
|
Logger.debug("Couldn't finger #{account}: #{inspect(error)}")
|
||||||
error
|
error
|
||||||
end
|
end
|
||||||
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
|
||||||
|
{:ok, data}
|
||||||
|
else
|
||||||
|
_ -> {:error, {:webfinger_invalid, url, data}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp validate_webfinger(url, data), do: {:error, {:webfinger_invalid, url, data}}
|
||||||
end
|
end
|
||||||
|
4
test/fixtures/tesla_mock/gleasonator.com_host_meta
vendored
Normal file
4
test/fixtures/tesla_mock/gleasonator.com_host_meta
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||||
|
<Link rel="lrdd" template="https://gleasonator.com/.well-known/webfinger?resource={uri}" type="application/xrd+xml" />
|
||||||
|
</XRD>
|
28
test/fixtures/tesla_mock/webfinger_spoof.json
vendored
Normal file
28
test/fixtures/tesla_mock/webfinger_spoof.json
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"aliases": [
|
||||||
|
"https://gleasonator.com/users/alex",
|
||||||
|
"https://mitra.social/users/alex"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "https://gleasonator.com/users/alex",
|
||||||
|
"rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
"type": "text/html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "https://gleasonator.com/users/alex",
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/activity+json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "https://gleasonator.com/users/alex",
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
"template": "https://gleasonator.com/ostatus_subscribe?acct={uri}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subject": "acct:trump@whitehouse.gov"
|
||||||
|
}
|
41
test/fixtures/webfinger/graf-imposter-webfinger.json
vendored
Normal file
41
test/fixtures/webfinger/graf-imposter-webfinger.json
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"subject": "acct:graf@poa.st",
|
||||||
|
"aliases": [
|
||||||
|
"https://fba.ryona.agenc/webfingertest"
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "http://webfinger.net/rel/profile-page",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "https://fba.ryona.agenc/webfingertest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"type": "application/activity+json",
|
||||||
|
"href": "https://fba.ryona.agenc/webfingertest"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
|
"template": "https://fba.ryona.agenc/contact/follow?url={uri}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://schemas.google.com/g/2010#updates-from",
|
||||||
|
"type": "application/atom+xml",
|
||||||
|
"href": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "salmon",
|
||||||
|
"href": "https://fba.ryona.agenc/salmon/friendica"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://microformats.org/profile/hcard",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "https://fba.ryona.agenc/hcard/friendica"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "http://joindiaspora.com/seed_location",
|
||||||
|
"type": "text/html",
|
||||||
|
"href": "https://fba.ryona.agenc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -76,15 +76,6 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||||||
{:ok, _data} = WebFinger.finger(user)
|
{:ok, _data} = WebFinger.finger(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns the ActivityPub actor URI and subscribe address for an ActivityPub user with the ld+json mimetype" do
|
|
||||||
user = "kaniini@gerzilla.de"
|
|
||||||
|
|
||||||
{:ok, data} = WebFinger.finger(user)
|
|
||||||
|
|
||||||
assert data["ap_id"] == "https://gerzilla.de/channel/kaniini"
|
|
||||||
assert data["subscribe_address"] == "https://gerzilla.de/follow?f=&url={uri}"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it work for AP-only user" do
|
test "it work for AP-only user" do
|
||||||
user = "kpherox@mstdn.jp"
|
user = "kpherox@mstdn.jp"
|
||||||
|
|
||||||
@ -99,12 +90,6 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||||||
assert data["subscribe_address"] == "https://mstdn.jp/authorize_interaction?acct={uri}"
|
assert data["subscribe_address"] == "https://mstdn.jp/authorize_interaction?acct={uri}"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works for friendica" do
|
|
||||||
user = "lain@squeet.me"
|
|
||||||
|
|
||||||
{:ok, _data} = WebFinger.finger(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
test "it gets the xrd endpoint" do
|
test "it gets the xrd endpoint" do
|
||||||
{:ok, template} = WebFinger.find_lrdd_template("social.heldscal.la")
|
{:ok, template} = WebFinger.find_lrdd_template("social.heldscal.la")
|
||||||
|
|
||||||
@ -203,5 +188,44 @@ defmodule Pleroma.Web.WebFingerTest do
|
|||||||
|
|
||||||
assert :error = WebFinger.finger("pekorino@pawoo.net")
|
assert :error = WebFinger.finger("pekorino@pawoo.net")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "prevents spoofing" do
|
||||||
|
Tesla.Mock.mock(fn
|
||||||
|
%{
|
||||||
|
url: "https://gleasonator.com/.well-known/webfinger?resource=acct:alex@gleasonator.com"
|
||||||
|
} ->
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/tesla_mock/webfinger_spoof.json"),
|
||||||
|
headers: [{"content-type", "application/jrd+json"}]
|
||||||
|
}}
|
||||||
|
|
||||||
|
%{url: "https://gleasonator.com/.well-known/host-meta"} ->
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/tesla_mock/gleasonator.com_host_meta")
|
||||||
|
}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:error, _data} = WebFinger.finger("alex@gleasonator.com")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@tag capture_log: true
|
||||||
|
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)
|
||||||
|
|
||||||
|
%{url: "https://fba.ryona.agency/.well-known/host-meta"} ->
|
||||||
|
{:ok, %Tesla.Env{status: 404}}
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, _} = WebFinger.finger("graf@fba.ryona.agency")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user