5
5
"net/http"
6
6
"strings"
7
7
8
+ "github.com/coder/coder/v2/coderd/proxyhealth"
8
9
"github.com/coder/coder/v2/codersdk"
9
10
)
10
11
@@ -47,18 +48,18 @@ const (
47
48
// for coderd.
48
49
//
49
50
// 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.
55
56
// - staticAdditions: a map of CSP directives to append to the default CSP headers.
56
57
// Used to allow specific static additions to the CSP headers. Allows some niche
57
58
// use cases, such as embedding Coder in an iframe.
58
59
// Example: https://github.com/coder/coder/issues/15118
59
60
//
60
61
//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 {
62
63
return func (next http.Handler ) http.Handler {
63
64
return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
64
65
// 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
97
98
// "require-trusted-types-for" : []string{"'script'"},
98
99
}
99
100
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
-
109
101
if telemetry {
110
102
// If telemetry is enabled, we report to coder.com.
111
103
cspSrcs .Append (CSPDirectiveConnectSrc , "https://coder.com" )
@@ -126,19 +118,26 @@ func CSPHeaders(experiments codersdk.Experiments, telemetry bool, websocketHosts
126
118
cspSrcs .Append (CSPDirectiveConnectSrc , fmt .Sprintf ("wss://%[1]s ws://%[1]s" , host ))
127
119
}
128
120
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 ()
132
124
if len (extraConnect ) > 0 {
133
125
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 == "*" {
135
131
// '*' means all
136
132
cspSrcs .Append (CSPDirectiveConnectSrc , "*" )
137
133
continue
138
134
}
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
+ }
140
139
// 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 ))
142
141
}
143
142
}
144
143
0 commit comments