Repository: phoenixframework/phoenix (elixir)

Issue:
Updated generated configuration to include headers and discussion on Spectre mitigation
At WWDC Apple gave a talk about security and safari. Specifically what is needed to defend against attacks like Spectre: https://developer.apple.com/videos/play/wwdc2018/207/

There are some additional headers they are supporting like `Cross-Origin-Window-Policy` which is needed to prevent an attacker from loading your site in a frame within their site which would allow the attacker to exploit Spectre. 

I think it's likely worthwhile to have this set by default:
`Cross-Origin-Window-Policy: deny` 
but we probably need documentation around it and discussion of the consequences.

It may also be worthwhile mentioning the techniques for guarding against an attacker compromising a CDN or replace hosted javascript files. But it's not clear to me where the best place to do this would be.

Pull request description:
Add security header to avoid window control attacks - Closes #2906
Hello guys,

This PR adds a new security header that avoid window control attacks as described on issue #2906.

As mentioned in the issue/[presentation](https://developer.apple.com/videos/play/wwdc2018/207/) this new header is already [released on Safari 12](https://developer.apple.com/safari/whats-new/).

PS: This is my first contribution to an Elixir project so please let me know if I need to do something more. The `level:starter` tag was helpful. 👍 




Patch:
diff --git a/lib/phoenix/controller.ex b/lib/phoenix/controller.ex
index 63bb144e3..cd2a431ba 100644
--- a/lib/phoenix/controller.ex
+++ b/lib/phoenix/controller.ex
@@ -998,6 +998,8 @@ defmodule Phoenix.Controller do
         context of the application (like critical domain cookies)
       * x-permitted-cross-domain-policies - set to none to restrict
         Adobe Flash Player’s access to data
+      * cross-origin-window-policy - set to deny to avoid window
+        control attacks
 
   A custom headers map may also be given to be merged with defaults.
   """
@@ -1016,7 +1018,8 @@ defmodule Phoenix.Controller do
       {"x-xss-protection", "1; mode=block"},
       {"x-content-type-options", "nosniff"},
       {"x-download-options", "noopen"},
-      {"x-permitted-cross-domain-policies", "none"}
+      {"x-permitted-cross-domain-policies", "none"},
+      {"cross-origin-window-policy", "deny"}
     ])
   end
 


Test patch:
diff --git a/test/phoenix/controller/controller_test.exs b/test/phoenix/controller/controller_test.exs
index 870187fcd..817dd6327 100644
--- a/test/phoenix/controller/controller_test.exs
+++ b/test/phoenix/controller/controller_test.exs
@@ -527,6 +527,7 @@ defmodule Phoenix.Controller.ControllerTest do
     assert get_resp_header(conn, "x-content-type-options") == ["nosniff"]
     assert get_resp_header(conn, "x-download-options") == ["noopen"]
     assert get_resp_header(conn, "x-permitted-cross-domain-policies") == ["none"]
+    assert get_resp_header(conn, "cross-origin-window-policy") == ["deny"]
 
     custom_headers = %{"x-frame-options" => "custom", "foo" => "bar"}
     conn = conn(:get, "/") |> put_secure_browser_headers(custom_headers)
@@ -534,6 +535,7 @@ defmodule Phoenix.Controller.ControllerTest do
     assert get_resp_header(conn, "x-xss-protection") == ["1; mode=block"]
     assert get_resp_header(conn, "x-download-options") == ["noopen"]
     assert get_resp_header(conn, "x-permitted-cross-domain-policies") == ["none"]
+    assert get_resp_header(conn, "cross-origin-window-policy") == ["deny"]
     assert get_resp_header(conn, "foo") == ["bar"]
   end