Browse Source

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.
1570-levenshtein-distance-user-search
rinpatch 4 years ago
parent
commit
455a402c8a
2 changed files with 31 additions and 23 deletions
  1. +30
    -22
      lib/pleroma/plugs/http_security_plug.ex
  2. +1
    -1
      test/plugs/http_security_plug_test.exs

+ 30
- 22
lib/pleroma/plugs/http_security_plug.ex View File

@@ -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


+ 1
- 1
test/plugs/http_security_plug_test.exs View File

@@ -67,7 +67,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do

[csp] = Conn.get_resp_header(conn, "content-security-policy")

assert csp =~ ~r|report-uri https://endpoint.com; report-to csp-endpoint;|
assert csp =~ ~r|report-uri https://endpoint.com;report-to csp-endpoint;|

[reply_to] = Conn.get_resp_header(conn, "reply-to")



Loading…
Cancel
Save