fix(coderd): add frame-ancestors CSP directive to prevent clickjacking (#24474)

This commit is contained in:
Jakub Domeracki
2026-04-20 13:01:46 +02:00
committed by GitHub
parent 467430d8fa
commit 615be176b8
3 changed files with 83 additions and 20 deletions
+7
View File
@@ -142,6 +142,13 @@ func CSPHeaders(telemetry bool, proxyHosts func() []*proxyhealth.ProxyHost, stat
cspSrcs.Append(directive, values...)
}
// Default to 'self' to prevent clickjacking unless
// explicitly overridden via staticAdditions (e.g. for
// embeddable routes).
if _, ok := cspSrcs[CSPFrameAncestors]; !ok {
cspSrcs[CSPFrameAncestors] = []string{"'self'"}
}
var csp strings.Builder
for src, vals := range cspSrcs {
_, _ = fmt.Fprintf(&csp, "%s %s; ", src, strings.Join(vals, " "))
+39
View File
@@ -12,6 +12,45 @@ import (
"github.com/coder/coder/v2/coderd/proxyhealth"
)
func TestCSPFrameAncestors(t *testing.T) {
t.Parallel()
t.Run("DefaultSelf", func(t *testing.T) {
t.Parallel()
r := httptest.NewRequest(http.MethodGet, "/", nil)
rw := httptest.NewRecorder()
httpmw.CSPHeaders(false, func() []*proxyhealth.ProxyHost {
return nil
}, nil)(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusOK)
})).ServeHTTP(rw, r)
csp := rw.Header().Get("Content-Security-Policy")
require.Contains(t, csp, "frame-ancestors 'self'")
})
t.Run("OverrideViaStaticAdditions", func(t *testing.T) {
t.Parallel()
r := httptest.NewRequest(http.MethodGet, "/", nil)
rw := httptest.NewRecorder()
httpmw.CSPHeaders(false, func() []*proxyhealth.ProxyHost {
return nil
}, map[httpmw.CSPFetchDirective][]string{
httpmw.CSPFrameAncestors: {"*"},
})(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusOK)
})).ServeHTTP(rw, r)
csp := rw.Header().Get("Content-Security-Policy")
require.Contains(t, csp, "frame-ancestors *")
require.NotContains(t, csp, "frame-ancestors 'self'")
})
}
func TestCSP(t *testing.T) {
t.Parallel()