X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fpleroma%2Fweb%2Fplugs%2Fhttp_security_plug.ex;h=5f0b775bea9e1025b28bdbc03111308743f7c02a;hb=a5e98083f253c268bb1468bfaf358038e0e60147;hp=45aaf188e6b3039d12f2573c8d81ed721de364dc;hpb=409f694e4f90d34285b43c7e7afc594bc386d893;p=akkoma
diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex
index 45aaf188e..5f0b775be 100644
--- a/lib/pleroma/web/plugs/http_security_plug.ex
+++ b/lib/pleroma/web/plugs/http_security_plug.ex
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors
+# Copyright © 2017-2021 Pleroma Authors
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
@@ -13,27 +13,52 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
def call(conn, _options) do
if Config.get([:http_security, :enabled]) do
conn
- |> merge_resp_headers(headers())
+ |> merge_resp_headers(headers(conn))
|> maybe_send_sts_header(Config.get([:http_security, :sts]))
else
conn
end
end
- defp headers do
+ def primary_frontend do
+ with %{"name" => frontend} <- Config.get([:frontends, :primary]),
+ available <- Config.get([:frontends, :available]),
+ %{} = primary_frontend <- Map.get(available, frontend) do
+ {:ok, primary_frontend}
+ end
+ end
+
+ def custom_http_frontend_headers do
+ with {:ok, %{"custom-http-headers" => custom_headers}} <- primary_frontend() do
+ custom_headers
+ else
+ _ -> []
+ end
+ end
+
+ @spec headers(Plug.Conn.t()) :: [{String.t(), String.t()}]
+ def headers(conn) do
referrer_policy = Config.get([:http_security, :referrer_policy])
report_uri = Config.get([:http_security, :report_uri])
+ custom_http_frontend_headers = custom_http_frontend_headers()
headers = [
- {"x-xss-protection", "1; mode=block"},
+ {"x-xss-protection", "0"},
{"x-permitted-cross-domain-policies", "none"},
{"x-frame-options", "DENY"},
{"x-content-type-options", "nosniff"},
{"referrer-policy", referrer_policy},
- {"x-download-options", "noopen"},
- {"content-security-policy", csp_string()}
+ {"content-security-policy", csp_string(conn)},
+ {"permissions-policy", "interest-cohort=()"}
]
+ headers =
+ if custom_http_frontend_headers do
+ custom_http_frontend_headers ++ headers
+ else
+ headers
+ end
+
if report_uri do
report_group = %{
"group" => "csp-endpoint",
@@ -43,7 +68,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
]
}
- [{"reply-to", Jason.encode!(report_group)} | headers]
+ [{"report-to", Jason.encode!(report_group)} | headers]
else
headers
end
@@ -51,21 +76,20 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
static_csp_rules = [
"default-src 'none'",
- "base-uri 'self'",
+ "base-uri 'none'",
"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
+ defp csp_string(conn) 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])
-
+ %{assigns: %{csp_nonce: nonce}} = conn
+ nonce_tag = "nonce-" <> nonce
img_src = "img-src 'self' data: blob:"
media_src = "media-src 'self'"
@@ -79,20 +103,22 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
{[img_src, " https:"], [media_src, " https:"]}
end
- connect_src = ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
-
connect_src =
- if Config.get(:env) == :dev do
- [connect_src, " http://localhost:3035/"]
+ if Config.get([:media_proxy, :enabled]) do
+ sources = build_csp_multimedia_source_list()
+ ["connect-src 'self' blob: ", static_url, ?\s, websocket_url, ?\s, sources]
else
- connect_src
+ ["connect-src 'self' blob: ", static_url, ?\s, websocket_url]
end
+ style_src = "style-src 'self' 'unsafe-inline'"
+ font_src = "font-src 'self' data:"
+
script_src =
if Config.get(:env) == :dev do
- "script-src 'self' 'unsafe-eval'"
+ "script-src 'self' 'unsafe-eval' '#{nonce_tag}'"
else
- "script-src 'self'"
+ "script-src 'self' '#{nonce_tag}'"
end
report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"]
@@ -103,6 +129,8 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
|> add_csp_param(media_src)
|> add_csp_param(connect_src)
|> add_csp_param(script_src)
+ |> add_csp_param(font_src)
+ |> add_csp_param(style_src)
|> add_csp_param(insecure)
|> add_csp_param(report)
|> :erlang.iolist_to_binary()
@@ -213,11 +241,9 @@ your instance and your users via malicious posts:
defp maybe_send_sts_header(conn, true) do
max_age_sts = Config.get([:http_security, :sts_max_age])
- max_age_ct = Config.get([:http_security, :ct_max_age])
merge_resp_headers(conn, [
- {"strict-transport-security", "max-age=#{max_age_sts}; includeSubDomains"},
- {"expect-ct", "enforce, max-age=#{max_age_ct}"}
+ {"strict-transport-security", "max-age=#{max_age_sts}; includeSubDomains; preload"}
])
end