From edb2314ad3ffc79d41f4d55eb7eda00331f9535a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 29 May 2025 09:15:58 -0500 Subject: [PATCH 1/4] feat: allow iframing urls on the same domain as the deployment Used for AI tasks --- coderd/httpmw/csp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/httpmw/csp.go b/coderd/httpmw/csp.go index e6864b7448c41..9d893e7230f56 100644 --- a/coderd/httpmw/csp.go +++ b/coderd/httpmw/csp.go @@ -88,7 +88,7 @@ func CSPHeaders(telemetry bool, websocketHosts func() []string, staticAdditions CSPDirectiveMediaSrc: {"'self'"}, // Report all violations back to the server to log CSPDirectiveReportURI: {"/api/v2/csp/reports"}, - CSPFrameAncestors: {"'none'"}, + CSPFrameAncestors: {"'self'"}, // Only scripts can manipulate the dom. This prevents someone from // naming themselves something like ''. From 648c7070d4db5ed997d5a3cfac934ddc6efd7421 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 29 May 2025 09:42:37 -0500 Subject: [PATCH 2/4] chore: toggle with experiment --- coderd/coderd.go | 24 +++++++++++++----------- coderd/httpmw/csp.go | 13 +++++++++++-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/coderd/coderd.go b/coderd/coderd.go index 37e7d22a6d080..0aab4b26262ea 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -1532,17 +1532,19 @@ func New(options *Options) *API { // Add CSP headers to all static assets and pages. CSP headers only affect // browsers, so these don't make sense on api routes. - cspMW := httpmw.CSPHeaders(options.Telemetry.Enabled(), func() []string { - if api.DeploymentValues.Dangerous.AllowAllCors { - // In this mode, allow all external requests - return []string{"*"} - } - if f := api.WorkspaceProxyHostsFn.Load(); f != nil { - return (*f)() - } - // By default we do not add extra websocket connections to the CSP - return []string{} - }, additionalCSPHeaders) + cspMW := httpmw.CSPHeaders( + api.Experiments, + options.Telemetry.Enabled(), func() []string { + if api.DeploymentValues.Dangerous.AllowAllCors { + // In this mode, allow all external requests + return []string{"*"} + } + if f := api.WorkspaceProxyHostsFn.Load(); f != nil { + return (*f)() + } + // By default we do not add extra websocket connections to the CSP + return []string{} + }, additionalCSPHeaders) // Static file handler must be wrapped with HSTS handler if the // StrictTransportSecurityAge is set. We only need to set this header on diff --git a/coderd/httpmw/csp.go b/coderd/httpmw/csp.go index 9d893e7230f56..37f44cda4e916 100644 --- a/coderd/httpmw/csp.go +++ b/coderd/httpmw/csp.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" "strings" + + "github.com/coder/coder/v2/codersdk" ) // cspDirectives is a map of all csp fetch directives to their values. @@ -55,7 +57,7 @@ const ( // Example: https://github.com/coder/coder/issues/15118 // //nolint:revive -func CSPHeaders(telemetry bool, websocketHosts func() []string, staticAdditions map[CSPFetchDirective][]string) func(next http.Handler) http.Handler { +func CSPHeaders(experiments codersdk.Experiments, telemetry bool, websocketHosts func() []string, staticAdditions map[CSPFetchDirective][]string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Content-Security-Policy disables loading certain content types and can prevent XSS injections. @@ -88,13 +90,20 @@ func CSPHeaders(telemetry bool, websocketHosts func() []string, staticAdditions CSPDirectiveMediaSrc: {"'self'"}, // Report all violations back to the server to log CSPDirectiveReportURI: {"/api/v2/csp/reports"}, - CSPFrameAncestors: {"'self'"}, // Only scripts can manipulate the dom. This prevents someone from // naming themselves something like ''. // "require-trusted-types-for" : []string{"'script'"}, } + if experiments.Enabled(codersdk.ExperimentAITasks) { + // AI tasks use iframe embeds of local apps. + // TODO: Handle region domains too, not just path based apps + cspSrcs.Append(CSPFrameAncestors, `'self'`) + } else { + cspSrcs.Append(CSPFrameAncestors, `'none'`) + } + if telemetry { // If telemetry is enabled, we report to coder.com. cspSrcs.Append(CSPDirectiveConnectSrc, "https://coder.com") From b3ac3eece9118ed4b37fa2a4ed9b03486e06d4d7 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 29 May 2025 09:47:01 -0500 Subject: [PATCH 3/4] fixup test --- coderd/httpmw/csp_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coderd/httpmw/csp_test.go b/coderd/httpmw/csp_test.go index c5000d3a29370..bef6ab196eb6e 100644 --- a/coderd/httpmw/csp_test.go +++ b/coderd/httpmw/csp_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/coderd/httpmw" + "github.com/coder/coder/v2/codersdk" ) func TestCSPConnect(t *testing.T) { @@ -20,7 +21,7 @@ func TestCSPConnect(t *testing.T) { r := httptest.NewRequest(http.MethodGet, "/", nil) rw := httptest.NewRecorder() - httpmw.CSPHeaders(false, func() []string { + httpmw.CSPHeaders(codersdk.Experiments{}, false, func() []string { return expected }, map[httpmw.CSPFetchDirective][]string{ httpmw.CSPDirectiveMediaSrc: expectedMedia, From 95f3b617ada28ac810e68936386ca02a52bc3441 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 29 May 2025 09:50:22 -0500 Subject: [PATCH 4/4] also add frame-src --- coderd/httpmw/csp.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coderd/httpmw/csp.go b/coderd/httpmw/csp.go index 37f44cda4e916..afc19ddaf0c1f 100644 --- a/coderd/httpmw/csp.go +++ b/coderd/httpmw/csp.go @@ -39,6 +39,7 @@ const ( CSPDirectiveFormAction CSPFetchDirective = "form-action" CSPDirectiveMediaSrc CSPFetchDirective = "media-src" CSPFrameAncestors CSPFetchDirective = "frame-ancestors" + CSPFrameSource CSPFetchDirective = "frame-src" CSPDirectiveWorkerSrc CSPFetchDirective = "worker-src" ) @@ -100,6 +101,7 @@ func CSPHeaders(experiments codersdk.Experiments, telemetry bool, websocketHosts // AI tasks use iframe embeds of local apps. // TODO: Handle region domains too, not just path based apps cspSrcs.Append(CSPFrameAncestors, `'self'`) + cspSrcs.Append(CSPFrameSource, `'self'`) } else { cspSrcs.Append(CSPFrameAncestors, `'none'`) } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy