Implement blocklists for MediaProxy #574
6 changed files with 56 additions and 3 deletions
|
@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
## Added
|
||||||
|
- Added a new configuration option to the MediaProxy feature that allows the blocking of specific domains from using the media proxy or being explicitly allowed by the Content-Security-Policy.
|
||||||
|
- Please make sure instances you wanted to block media from are not in the MediaProxy `whitelist`, and instead use `blocklist`.
|
||||||
|
|
||||||
## 2023.05
|
## 2023.05
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
|
@ -443,7 +443,8 @@
|
||||||
# Note: max_read_duration defaults to Pleroma.ReverseProxy.max_read_duration_default/1
|
# Note: max_read_duration defaults to Pleroma.ReverseProxy.max_read_duration_default/1
|
||||||
max_read_duration: 30_000
|
max_read_duration: 30_000
|
||||||
],
|
],
|
||||||
whitelist: []
|
whitelist: [],
|
||||||
|
blocklist: []
|
||||||
|
|
||||||
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
|
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
|
||||||
method: :purge,
|
method: :purge,
|
||||||
|
|
|
@ -1558,7 +1558,21 @@
|
||||||
%{
|
%{
|
||||||
key: :whitelist,
|
key: :whitelist,
|
||||||
type: {:list, :string},
|
type: {:list, :string},
|
||||||
description: "List of hosts with scheme to bypass the MediaProxy",
|
description: """
|
||||||
|
List of hosts with scheme to bypass the MediaProxy.\n
|
||||||
|
The media will be fetched by the client, directly from the remote server.\n
|
||||||
|
To allow this, it will Content-Security-Policy exceptions for each instance listed.\n
|
||||||
|
This is to be used for instances you trust and do not want to cache media for.
|
||||||
|
""",
|
||||||
|
suggestions: ["http://example.com"]
|
||||||
|
},
|
||||||
|
%{
|
||||||
|
key: :blocklist,
|
||||||
|
type: {:list, :string},
|
||||||
|
description: """
|
||||||
|
List of hosts with scheme which will not go through the MediaProxy, and will not be explicitly allowed by the Content-Security-Policy.
|
||||||
|
This is to be used for instances where you do not want their media to go through your server or to be accessed by clients.
|
||||||
|
""",
|
||||||
suggestions: ["http://example.com"]
|
suggestions: ["http://example.com"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -52,7 +52,7 @@ def url(url) do
|
||||||
|
|
||||||
@spec url_proxiable?(String.t()) :: boolean()
|
@spec url_proxiable?(String.t()) :: boolean()
|
||||||
def url_proxiable?(url) do
|
def url_proxiable?(url) do
|
||||||
not local?(url) and not whitelisted?(url)
|
not local?(url) and not whitelisted?(url) and not blocked?(url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def preview_url(url, preview_params \\ []) do
|
def preview_url(url, preview_params \\ []) do
|
||||||
|
@ -83,6 +83,11 @@ def whitelisted?(url) do
|
||||||
domain in mediaproxy_whitelist_domains
|
domain in mediaproxy_whitelist_domains
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def blocked?(url) do
|
||||||
|
%{host: domain} = URI.parse(url)
|
||||||
|
domain in Config.get([:media_proxy, :whitelist])
|
||||||
|
end
|
||||||
|
|
||||||
defp maybe_get_domain_from_url("http" <> _ = url) do
|
defp maybe_get_domain_from_url("http" <> _ = url) do
|
||||||
URI.parse(url).host
|
URI.parse(url).host
|
||||||
end
|
end
|
||||||
|
|
|
@ -199,6 +199,15 @@ test "mediaproxy whitelist" do
|
||||||
assert unencoded == url
|
assert unencoded == url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "mediaproxy blocklist" do
|
||||||
|
clear_config([:media_proxy, :whitelist], ["https://google.com"])
|
||||||
|
clear_config([:media_proxy, :blocklist], ["https://feld.me"])
|
||||||
|
url = "https://feld.me/foo.png"
|
||||||
|
|
||||||
|
unencoded = MediaProxy.url(url)
|
||||||
|
assert unencoded == url
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: delete after removing support bare domains for media proxy whitelist
|
# TODO: delete after removing support bare domains for media proxy whitelist
|
||||||
test "mediaproxy whitelist bare domains whitelist (deprecated)" do
|
test "mediaproxy whitelist bare domains whitelist (deprecated)" do
|
||||||
clear_config([:media_proxy, :whitelist], ["google.com", "feld.me"])
|
clear_config([:media_proxy, :whitelist], ["google.com", "feld.me"])
|
||||||
|
@ -220,6 +229,18 @@ test "does not change whitelisted urls" do
|
||||||
assert String.starts_with?(encoded, media_url)
|
assert String.starts_with?(encoded, media_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "does not change blocked urls" do
|
||||||
|
clear_config([:media_proxy, :whitelist], ["mycdn.akamai.com"])
|
||||||
|
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
|
||||||
|
|
||||||
|
media_url = "https://mycdn.akamai.com"
|
||||||
|
|
||||||
|
url = "#{media_url}/static/logo.png"
|
||||||
|
encoded = MediaProxy.url(url)
|
||||||
|
|
||||||
|
assert String.starts_with?(encoded, media_url)
|
||||||
|
end
|
||||||
|
|
||||||
test "ensure Pleroma.Upload base_url is always whitelisted" do
|
test "ensure Pleroma.Upload base_url is always whitelisted" do
|
||||||
media_url = "https://media.pleroma.social"
|
media_url = "https://media.pleroma.social"
|
||||||
clear_config([Pleroma.Upload, :base_url], media_url)
|
clear_config([Pleroma.Upload, :base_url], media_url)
|
||||||
|
|
|
@ -128,6 +128,12 @@ test "with media_proxy bare domains whitelist (deprecated)", %{conn: conn} do
|
||||||
clear_config([:media_proxy, :whitelist], ["example4.com", "example5.com"])
|
clear_config([:media_proxy, :whitelist], ["example4.com", "example5.com"])
|
||||||
assert_media_img_src(conn, "example5.com example4.com")
|
assert_media_img_src(conn, "example5.com example4.com")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "with media_proxy blocklist", %{conn: conn} do
|
||||||
|
clear_config([:media_proxy, :whitelist], ["https://example6.com", "https://example7.com"])
|
||||||
|
clear_config([:media_proxy, :blocklist], ["https://example8.com"])
|
||||||
|
assert_media_img_src(conn, "https://example7.com https://example6.com")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp assert_media_img_src(conn, url) do
|
defp assert_media_img_src(conn, url) do
|
||||||
|
|
Loading…
Reference in a new issue