mirror of
https://github.com/coder/coder.git
synced 2025-07-13 21:36:50 +00:00
feat: add csp headers for embedded apps (#18374)
I modified the proxy host cache we already had and were using for websocket csp headers to also include the wildcard app host, then used those for frame-src policies. I did not add frame-ancestors, since if I understand correctly, those would go on the app, and this middleware does not come into play there. Maybe we will want to add it on workspace apps like we do with cors, if we find apps are setting it to `none` or something. Closes https://github.com/coder/internal/issues/684
This commit is contained in:
@ -289,3 +289,23 @@ func ExecuteHostnamePattern(pattern *regexp.Regexp, hostname string) (string, bo
|
||||
|
||||
return matches[1], true
|
||||
}
|
||||
|
||||
// ConvertAppHostForCSP converts the wildcard host to a format accepted by CSP.
|
||||
// For example *--apps.coder.com must become *.coder.com. If there is no
|
||||
// wildcard host, or it cannot be converted, return the base host.
|
||||
func ConvertAppHostForCSP(host, wildcard string) string {
|
||||
if wildcard == "" {
|
||||
return host
|
||||
}
|
||||
parts := strings.Split(wildcard, ".")
|
||||
for i, part := range parts {
|
||||
if strings.Contains(part, "*") {
|
||||
// The wildcard can only be in the first section.
|
||||
if i != 0 {
|
||||
return host
|
||||
}
|
||||
parts[i] = "*"
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, ".")
|
||||
}
|
||||
|
@ -410,3 +410,59 @@ func TestCompileHostnamePattern(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertAppURLForCSP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
host string
|
||||
wildcard string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "Empty",
|
||||
host: "example.com",
|
||||
wildcard: "",
|
||||
expected: "example.com",
|
||||
},
|
||||
{
|
||||
name: "NoAsterisk",
|
||||
host: "example.com",
|
||||
wildcard: "coder.com",
|
||||
expected: "coder.com",
|
||||
},
|
||||
{
|
||||
name: "Asterisk",
|
||||
host: "example.com",
|
||||
wildcard: "*.coder.com",
|
||||
expected: "*.coder.com",
|
||||
},
|
||||
{
|
||||
name: "FirstPrefix",
|
||||
host: "example.com",
|
||||
wildcard: "*--apps.coder.com",
|
||||
expected: "*.coder.com",
|
||||
},
|
||||
{
|
||||
name: "FirstSuffix",
|
||||
host: "example.com",
|
||||
wildcard: "apps--*.coder.com",
|
||||
expected: "*.coder.com",
|
||||
},
|
||||
{
|
||||
name: "Middle",
|
||||
host: "example.com",
|
||||
wildcard: "apps.*.com",
|
||||
expected: "example.com",
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range testCases {
|
||||
c := c
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.Equal(t, c.expected, appurl.ConvertAppHostForCSP(c.host, c.wildcard))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user