55 "net/http"
66 "strings"
77
8+ "github.com/coder/coder/v2/coderd/proxyhealth"
89 "github.com/coder/coder/v2/codersdk"
910)
1011
@@ -47,18 +48,18 @@ const (
4748// for coderd.
4849//
4950// Arguments:
50- // - websocketHosts : a function that returns a list of supported external websocket hosts.
51- // This is to support the terminal connecting to a workspace proxy.
52- // The origin of the terminal request does not match the url of the proxy,
53- // so the CSP list of allowed hosts must be dynamic and match the current
54- // available proxy urls.
51+ // - proxyHosts : a function that returns a list of supported proxy hosts
52+ // (including the primary). This is to support the terminal connecting to a
53+ // workspace proxy and for embedding apps in an iframe. The origin of the
54+ // requests do not match the url of the proxy, so the CSP list of allowed
55+ // hosts must be dynamic and match the current available proxy urls.
5556// - staticAdditions: a map of CSP directives to append to the default CSP headers.
5657// Used to allow specific static additions to the CSP headers. Allows some niche
5758// use cases, such as embedding Coder in an iframe.
5859// Example: https://github.com/coder/coder/issues/15118
5960//
6061//nolint:revive
61- func CSPHeaders (experiments codersdk.Experiments , telemetry bool , websocketHosts func () []string , staticAdditions map [CSPFetchDirective ][]string ) func (next http.Handler ) http.Handler {
62+ func CSPHeaders (experiments codersdk.Experiments , telemetry bool , proxyHosts func () []* proxyhealth. ProxyHost , staticAdditions map [CSPFetchDirective ][]string ) func (next http.Handler ) http.Handler {
6263 return func (next http.Handler ) http.Handler {
6364 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
6465 // Content-Security-Policy disables loading certain content types and can prevent XSS injections.
@@ -97,15 +98,6 @@ func CSPHeaders(experiments codersdk.Experiments, telemetry bool, websocketHosts
9798 // "require-trusted-types-for" : []string{"'script'"},
9899 }
99100
100- if experiments .Enabled (codersdk .ExperimentAITasks ) {
101- // AI tasks use iframe embeds of local apps.
102- // TODO: Handle region domains too, not just path based apps
103- cspSrcs .Append (CSPFrameAncestors , `'self'` )
104- cspSrcs .Append (CSPFrameSource , `'self'` )
105- } else {
106- cspSrcs .Append (CSPFrameAncestors , `'none'` )
107- }
108-
109101 if telemetry {
110102 // If telemetry is enabled, we report to coder.com.
111103 cspSrcs .Append (CSPDirectiveConnectSrc , "https://coder.com" )
@@ -126,19 +118,26 @@ func CSPHeaders(experiments codersdk.Experiments, telemetry bool, websocketHosts
126118 cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("wss://%[1]s ws://%[1]s" , host ))
127119 }
128120
129- // The terminal requires a websocket connection to the workspace proxy.
130- // Make sure we allow this connection to healthy proxies.
131- extraConnect := websocketHosts ()
121+ // The terminal and iframed apps can use workspace proxies (which includes
122+ // the primary). Make sure we allow connections to healthy proxies.
123+ extraConnect := proxyHosts ()
132124 if len (extraConnect ) > 0 {
133125 for _ , extraHost := range extraConnect {
134- if extraHost == "*" {
126+ // Allow embedding the app host.
127+ if experiments .Enabled (codersdk .ExperimentAITasks ) {
128+ cspSrcs .Append (CSPDirectiveFrameSrc , extraHost .AppHost )
129+ }
130+ if extraHost .Host == "*" {
135131 // '*' means all
136132 cspSrcs .Append (CSPDirectiveConnectSrc , "*" )
137133 continue
138134 }
139- cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("wss://%[1]s ws://%[1]s" , extraHost ))
135+ // Avoid double-adding r.Host.
136+ if extraHost .Host != r .Host {
137+ cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("wss://%[1]s ws://%[1]s" , extraHost .Host ))
138+ }
140139 // We also require this to make http/https requests to the workspace proxy for latency checking.
141- cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("https://%[1]s http://%[1]s" , extraHost ))
140+ cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("https://%[1]s http://%[1]s" , extraHost . Host ))
142141 }
143142 }
144143
0 commit comments