fix: restrict WebSocket CSP to request scheme
This commit is contained in:
parent
b8e122056e
commit
9b51d0807b
|
|
@ -9,15 +9,14 @@ defmodule WhoNeedHelpWeb.SecurityHeaders do
|
|||
|> Application.fetch_env!(:map_tile_url)
|
||||
|> origin()
|
||||
|
||||
websocket_origins =
|
||||
[
|
||||
origin(%URI{scheme: "ws", host: conn.host, port: conn.port}),
|
||||
origin(%URI{scheme: "wss", host: conn.host, port: default_https_port(conn)})
|
||||
]
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.uniq()
|
||||
websocket_origin =
|
||||
case conn.scheme do
|
||||
:http -> origin(%URI{scheme: "ws", host: conn.host, port: conn.port})
|
||||
:https -> origin(%URI{scheme: "wss", host: conn.host, port: conn.port})
|
||||
_other -> nil
|
||||
end
|
||||
|
||||
connect_sources = sources(["'self'", tile_origin | websocket_origins])
|
||||
connect_sources = sources(["'self'", tile_origin, websocket_origin])
|
||||
image_sources = sources(["'self'", "data:", "blob:", tile_origin])
|
||||
|
||||
policy =
|
||||
|
|
@ -39,9 +38,6 @@ defmodule WhoNeedHelpWeb.SecurityHeaders do
|
|||
put_resp_header(conn, "content-security-policy", policy)
|
||||
end
|
||||
|
||||
defp default_https_port(%Plug.Conn{port: 443}), do: 443
|
||||
defp default_https_port(_conn), do: nil
|
||||
|
||||
defp sources(values),
|
||||
do: values |> Enum.reject(&is_nil/1) |> Enum.uniq() |> Enum.join(" ")
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ defmodule WhoNeedHelpWeb.PageControllerTest do
|
|||
refute content_security_policy =~ "script-src 'self' 'unsafe-inline'"
|
||||
assert content_security_policy =~ "frame-ancestors 'none'"
|
||||
assert content_security_policy =~ "https://tile.openstreetmap.org"
|
||||
assert content_security_policy =~ "ws://www.example.com"
|
||||
refute content_security_policy =~ "wss://www.example.com"
|
||||
|
||||
assert get_resp_header(conn, "permissions-policy") == [
|
||||
"geolocation=(self), camera=(), microphone=(), payment=(), usb=()"
|
||||
|
|
@ -38,6 +40,20 @@ defmodule WhoNeedHelpWeb.PageControllerTest do
|
|||
) == 1
|
||||
end
|
||||
|
||||
test "HTTPS content security policy permits only secure WebSockets", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> Map.put(:scheme, :https)
|
||||
|> Map.put(:host, "help.example")
|
||||
|> Map.put(:port, 443)
|
||||
|> WhoNeedHelpWeb.SecurityHeaders.put_content_security_policy([])
|
||||
|
||||
[content_security_policy] = get_resp_header(conn, "content-security-policy")
|
||||
|
||||
assert content_security_policy =~ "wss://help.example"
|
||||
refute content_security_policy =~ "ws://help.example"
|
||||
end
|
||||
|
||||
test "Phoenix logs filter authentication and handover secrets" do
|
||||
assert Phoenix.Logger.filter_values(%{
|
||||
"password" => "not-logged",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user