Skip to content
Snippets Groups Projects
Commit 24c3e2db authored by feld's avatar feld
Browse files

Add mediaproxy whitelist capability

parent 8c9227c1
No related branches found
No related tags found
No related merge requests found
...@@ -326,7 +326,8 @@ config :pleroma, :media_proxy, ...@@ -326,7 +326,8 @@ config :pleroma, :media_proxy,
follow_redirect: true, follow_redirect: true,
pool: :media pool: :media
] ]
] ],
whitelist: []
config :pleroma, :chat, enabled: true config :pleroma, :chat, enabled: true
......
...@@ -205,6 +205,7 @@ This section is used to configure Pleroma-FE, unless ``:managed_config`` in ``:i ...@@ -205,6 +205,7 @@ This section is used to configure Pleroma-FE, unless ``:managed_config`` in ``:i
* `enabled`: Enables proxying of remote media to the instance’s proxy * `enabled`: Enables proxying of remote media to the instance’s proxy
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts. * `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.
* `proxy_opts`: All options defined in `Pleroma.ReverseProxy` documentation, defaults to `[max_body_length: (25*1_048_576)]`. * `proxy_opts`: All options defined in `Pleroma.ReverseProxy` documentation, defaults to `[max_body_length: (25*1_048_576)]`.
* `whitelist`: List of domains to bypass the mediaproxy
## :gopher ## :gopher
* `enabled`: Enables the gopher interface * `enabled`: Enables the gopher interface
......
...@@ -13,32 +13,44 @@ defmodule Pleroma.Web.MediaProxy do ...@@ -13,32 +13,44 @@ defmodule Pleroma.Web.MediaProxy do
def url(url) do def url(url) do
config = Application.get_env(:pleroma, :media_proxy, []) config = Application.get_env(:pleroma, :media_proxy, [])
domain = URI.parse(url).host
if !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url()) do cond do
url !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url()) ->
else
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
# Must preserve `%2F` for compatibility with S3
# https://git.pleroma.social/pleroma/pleroma/issues/580
replacement = get_replacement(url, ":2F:")
# The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice.
base64 =
url url
|> String.replace("%2F", replacement)
|> URI.decode()
|> URI.encode()
|> String.replace(replacement, "%2F")
|> Base.url_encode64(@base64_opts)
sig = :crypto.hmac(:sha, secret, base64) Enum.any?(Pleroma.Config.get([:media_proxy, :whitelist]), fn pattern ->
sig64 = sig |> Base.url_encode64(@base64_opts) String.equivalent?(domain, pattern)
end) ->
url
build_url(sig64, base64, filename(url)) true ->
encode_url(url)
end end
end end
def encode_url(url) do
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
# Must preserve `%2F` for compatibility with S3
# https://git.pleroma.social/pleroma/pleroma/issues/580
replacement = get_replacement(url, ":2F:")
# The URL is url-decoded and encoded again to ensure it is correctly encoded and not twice.
base64 =
url
|> String.replace("%2F", replacement)
|> URI.decode()
|> URI.encode()
|> String.replace(replacement, "%2F")
|> Base.url_encode64(@base64_opts)
sig = :crypto.hmac(:sha, secret, base64)
sig64 = sig |> Base.url_encode64(@base64_opts)
build_url(sig64, base64, filename(url))
end
def decode_url(sig, url) do def decode_url(sig, url) do
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base] secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
sig = Base.url_decode64!(sig, @base64_opts) sig = Base.url_decode64!(sig, @base64_opts)
......
...@@ -177,4 +177,13 @@ defmodule Pleroma.MediaProxyTest do ...@@ -177,4 +177,13 @@ defmodule Pleroma.MediaProxyTest do
{:ok, decoded} = decode_url(sig, base64) {:ok, decoded} = decode_url(sig, base64)
decoded decoded
end end
test "mediaproxy whitelist" do
Pleroma.Config.put([:media_proxy, :enabled], true)
Pleroma.Config.put([:media_proxy, :whitelist], ["google.com", "feld.me"])
url = "https://feld.me/foo.png"
unencoded = url(url)
assert unencoded == url
end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment