From e0a5b3620da0dd0e5c7d1f424033d2e847be84fc Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Mon, 12 Sep 2022 16:59:54 -0400 Subject: [PATCH] MM-46004 Add Focalboard webpack dev server to dev CSP policy (#20888) * MM-46004 Add Focalboard webpack dev server to dev CSP policy * Fix tests and prevent duplicated CSP values --- web/handlers.go | 31 ++++++++++++++++++++----------- web/handlers_test.go | 8 ++++---- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/web/handlers.go b/web/handlers.go index 777a8ebcad..f0faa7abe3 100644 --- a/web/handlers.go +++ b/web/handlers.go @@ -87,16 +87,17 @@ type Handler struct { } func generateDevCSP(c Context) string { + var devCSP []string + // Add unsafe-eval to the content security policy for faster source maps in development mode - devCSPMap := make(map[string]bool) if model.BuildNumber == "dev" { - devCSPMap["unsafe-eval"] = true + devCSP = append(devCSP, "'unsafe-eval'") } // Add unsafe-inline to unlock extensions like React & Redux DevTools in Firefox // see https://github.com/reduxjs/redux-devtools/issues/380 if model.BuildNumber == "dev" { - devCSPMap["unsafe-inline"] = true + devCSP = append(devCSP, "'unsafe-inline'") } // Add supported flags for debugging during development, even if not on a dev build. @@ -118,21 +119,29 @@ func generateDevCSP(c Context) string { // Honour only supported keys switch devFlagKey { case "unsafe-eval", "unsafe-inline": - devCSPMap[devFlagKey] = true + if model.BuildNumber == "dev" { + // These flags are added automatically for dev builds + continue + } + + devCSP = append(devCSP, "'"+devFlagKey+"'") default: c.Logger.Warn("Unrecognized developer flag", mlog.String("developer_flag", devFlagKVStr)) } } } - var devCSP string - supportedCSPFlags := []string{"unsafe-eval", "unsafe-inline"} - for _, devCSPFlag := range supportedCSPFlags { - if devCSPMap[devCSPFlag] { - devCSP += fmt.Sprintf(" '%s'", devCSPFlag) - } + + // Add flags for Webpack dev servers used by other products during development + if model.BuildNumber == "dev" { + // Focalboard runs on http://localhost:9006 + devCSP = append(devCSP, "http://localhost:9006") } - return devCSP + if len(devCSP) == 0 { + return "" + } + + return " " + strings.Join(devCSP, " ") } func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/web/handlers_test.go b/web/handlers_test.go index 4651bb99e6..906a464b39 100644 --- a/web/handlers_test.go +++ b/web/handlers_test.go @@ -388,7 +388,7 @@ func TestHandlerServeCSPHeader(t *testing.T) { response := httptest.NewRecorder() handler.ServeHTTP(response, request) assert.Equal(t, 200, response.Code) - assert.Equal(t, []string{"frame-ancestors 'self'; script-src 'self' cdn.rudderlabs.com 'unsafe-eval' 'unsafe-inline'"}, response.Header()["Content-Security-Policy"]) + assert.Equal(t, []string{"frame-ancestors 'self'; script-src 'self' cdn.rudderlabs.com 'unsafe-eval' 'unsafe-inline' http://localhost:9006"}, response.Header()["Content-Security-Policy"]) }) } @@ -411,9 +411,9 @@ func TestGenerateDevCSP(t *testing.T) { devCSP := generateDevCSP(*c) - assert.Equal(t, " 'unsafe-eval' 'unsafe-inline'", devCSP) - + assert.Equal(t, " 'unsafe-eval' 'unsafe-inline' http://localhost:9006", devCSP) }) + t.Run("allowed dev flags", func(t *testing.T) { th := Setup(t) defer th.TearDown() @@ -436,7 +436,7 @@ func TestGenerateDevCSP(t *testing.T) { devCSP := generateDevCSP(*c) - assert.Equal(t, " 'unsafe-eval' 'unsafe-inline'", devCSP) + assert.Equal(t, " 'unsafe-inline' 'unsafe-eval'", devCSP) }) t.Run("partial dev flags", func(t *testing.T) {