From 8f6d428880721d4b0151991e7943706b70ab8005 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Wed, 27 May 2020 19:35:35 +0300 Subject: AccountView: Use mediaproxy URLs for emojis Also use atom keys in emoji maps instead of binaries Closes #1810 --- lib/pleroma/web/mastodon_api/views/account_view.ex | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 45fffaad2..04c419d2f 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -182,12 +182,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do bot = user.actor_type in ["Application", "Service"] emojis = - Enum.map(user.emoji, fn {shortcode, url} -> + Enum.map(user.emoji, fn {shortcode, raw_url} -> + url = MediaProxy.url(raw_url) + %{ - "shortcode" => shortcode, - "url" => url, - "static_url" => url, - "visible_in_picker" => false + shortcode: shortcode, + url: url, + static_url: url, + visible_in_picker: false } end) -- cgit v1.2.3 From 455a402c8a967b3a234c836b0574c4f011860d43 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Wed, 27 May 2020 20:27:30 +0300 Subject: HTTP Security plug: rewrite &csp_string/0 - Directives are now separated with ";" instead of " ;", according to https://www.w3.org/TR/CSP2/#policy-parsing the space is optional - Use an IO list, which at the end gets converted to a binary as opposed to ++ing a bunch of arrays with binaries together and joining them to a string. I doubt it gives any significant real world advantage, but the code is cleaner and now I can sleep at night. - The static part of csp is pre-joined to a single binary at compile time. Same reasoning as the last point. --- lib/pleroma/plugs/http_security_plug.ex | 52 +++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex index 6462797b6..f9aff2fab 100644 --- a/lib/pleroma/plugs/http_security_plug.ex +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -31,7 +31,7 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do {"x-content-type-options", "nosniff"}, {"referrer-policy", referrer_policy}, {"x-download-options", "noopen"}, - {"content-security-policy", csp_string() <> ";"} + {"content-security-policy", csp_string()} ] if report_uri do @@ -43,23 +43,35 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do ] } - headers ++ [{"reply-to", Jason.encode!(report_group)}] + [{"reply-to", Jason.encode!(report_group)} | headers] else headers end end + @csp_start [ + "default-src 'none'", + "base-uri 'self'", + "frame-ancestors 'none'", + "style-src 'self' 'unsafe-inline'", + "font-src 'self'", + "manifest-src 'self'" + ] + |> Enum.join(";") + |> Kernel.<>(";") + |> List.wrap() + defp csp_string do scheme = Config.get([Pleroma.Web.Endpoint, :url])[:scheme] static_url = Pleroma.Web.Endpoint.static_url() websocket_url = Pleroma.Web.Endpoint.websocket_url() report_uri = Config.get([:http_security, :report_uri]) - connect_src = "connect-src 'self' #{static_url} #{websocket_url}" + connect_src = ["connect-src 'self' ", static_url, ?\s, websocket_url] connect_src = if Pleroma.Config.get(:env) == :dev do - connect_src <> " http://localhost:3035/" + [connect_src," http://localhost:3035/"] else connect_src end @@ -71,26 +83,22 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do "script-src 'self'" end - main_part = [ - "default-src 'none'", - "base-uri 'self'", - "frame-ancestors 'none'", - "img-src 'self' data: blob: https:", - "media-src 'self' https:", - "style-src 'self' 'unsafe-inline'", - "font-src 'self'", - "manifest-src 'self'", - connect_src, - script_src - ] - - report = if report_uri, do: ["report-uri #{report_uri}; report-to csp-endpoint"], else: [] + report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"] + insecure = if scheme == "https", do: "upgrade-insecure-requests" + + @csp_start + |> add_csp_param("img-src 'self' data: blob: https:") + |> add_csp_param("media-src 'self' https:") + |> add_csp_param(connect_src) + |> add_csp_param(script_src) + |> add_csp_param(insecure) + |> add_csp_param(report) + |> :erlang.iolist_to_binary() + end - insecure = if scheme == "https", do: ["upgrade-insecure-requests"], else: [] + defp add_csp_param(csp_iodata, nil), do: csp_iodata - (main_part ++ report ++ insecure) - |> Enum.join("; ") - end + defp add_csp_param(csp_iodata, param), do: [[param, ?;] | csp_iodata] def warn_if_disabled do unless Config.get([:http_security, :enabled]) do -- cgit v1.2.3 From 29ff6d414ba096e74e04264af895abcabcf580b4 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Wed, 27 May 2020 21:01:36 +0300 Subject: HTTP security plug: Harden img-src and media-src when MediaProxy is enabled --- lib/pleroma/plugs/http_security_plug.ex | 41 ++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex index f9aff2fab..df38d5022 100644 --- a/lib/pleroma/plugs/http_security_plug.ex +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -67,11 +67,23 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do websocket_url = Pleroma.Web.Endpoint.websocket_url() report_uri = Config.get([:http_security, :report_uri]) + img_src = "img-src 'self' data: blob:" + media_src = "media-src 'self'" + + {img_src, media_src} = + if Config.get([:media_proxy, :enabled]) && + !Config.get([:media_proxy, :proxy_opts, :redirect_on_failure]) do + sources = get_proxy_and_attachment_sources() + {[img_src, sources], [media_src, sources]} + else + {img_src, media_src} + end + connect_src = ["connect-src 'self' ", static_url, ?\s, websocket_url] connect_src = if Pleroma.Config.get(:env) == :dev do - [connect_src," http://localhost:3035/"] + [connect_src, " http://localhost:3035/"] else connect_src end @@ -87,8 +99,8 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do insecure = if scheme == "https", do: "upgrade-insecure-requests" @csp_start - |> add_csp_param("img-src 'self' data: blob: https:") - |> add_csp_param("media-src 'self' https:") + |> add_csp_param(img_src) + |> add_csp_param(media_src) |> add_csp_param(connect_src) |> add_csp_param(script_src) |> add_csp_param(insecure) @@ -96,6 +108,29 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do |> :erlang.iolist_to_binary() end + defp get_proxy_and_attachment_sources do + media_proxy_whitelist = + Enum.reduce(Config.get([:media_proxy, :whitelist]), [], fn host, acc -> + add_source(acc, host) + end) + + upload_base_url = + if Config.get([Pleroma.Upload, :base_url]), + do: URI.parse(Config.get([Pleroma.Upload, :base_url])).host + + s3_endpoint = + if Config.get([Pleroma.Upload, :uploader]) == Pleroma.Uploaders.S3, + do: URI.parse(Config.get([Pleroma.Uploaders.S3, :public_endpoint])).host + + [] + |> add_source(upload_base_url) + |> add_source(s3_endpoint) + |> add_source(media_proxy_whitelist) + end + + defp add_source(iodata, nil), do: iodata + defp add_source(iodata, source), do: [[?\s, source] | iodata] + defp add_csp_param(csp_iodata, nil), do: csp_iodata defp add_csp_param(csp_iodata, param), do: [[param, ?;] | csp_iodata] -- cgit v1.2.3 From 27180611dfffd064e65793f90c67dc16fff8ecc2 Mon Sep 17 00:00:00 2001 From: rinpatch Date: Fri, 29 May 2020 12:32:48 +0300 Subject: HTTP Security plug: make starting csp string generation more readable --- lib/pleroma/plugs/http_security_plug.ex | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/plugs/http_security_plug.ex b/lib/pleroma/plugs/http_security_plug.ex index df38d5022..2208d1d6c 100644 --- a/lib/pleroma/plugs/http_security_plug.ex +++ b/lib/pleroma/plugs/http_security_plug.ex @@ -49,17 +49,16 @@ defmodule Pleroma.Plugs.HTTPSecurityPlug do end end - @csp_start [ - "default-src 'none'", - "base-uri 'self'", - "frame-ancestors 'none'", - "style-src 'self' 'unsafe-inline'", - "font-src 'self'", - "manifest-src 'self'" - ] - |> Enum.join(";") - |> Kernel.<>(";") - |> List.wrap() + static_csp_rules = [ + "default-src 'none'", + "base-uri 'self'", + "frame-ancestors 'none'", + "style-src 'self' 'unsafe-inline'", + "font-src 'self'", + "manifest-src 'self'" + ] + + @csp_start [Enum.join(static_csp_rules, ";") <> ";"] defp csp_string do scheme = Config.get([Pleroma.Web.Endpoint, :url])[:scheme] -- cgit v1.2.3