[SEC-2191] Add security headers with sensible default values. (#21656)
* Add security headers with sensible default values. * Add test to check that default security headers are added to http responses * Also test the static handler.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
544304d1c6
Коммит
62428467dc
@@ -235,6 +235,11 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Strict-Transport-Security", fmt.Sprintf("max-age=%d", *c.App.Config().ServiceSettings.TLSStrictTransportMaxAge))
|
||||
}
|
||||
|
||||
// Hardcoded sensible default values for these security headers. Feel free to override in proxy or ingress
|
||||
w.Header().Set("Permissions-Policy", "")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("Referrer-Policy", "no-referrer")
|
||||
|
||||
cloudCSP := ""
|
||||
if c.App.Channels().License().IsCloud() || *c.App.Config().ServiceSettings.SelfHostedPurchase {
|
||||
cloudCSP = " js.stripe.com/v3"
|
||||
|
||||
@@ -59,6 +59,44 @@ func TestHandlerServeHTTPErrors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func handlerForServeDefaultSecurityHeaders(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func TestHandlerServeDefaultSecurityHeaders(t *testing.T) {
|
||||
th := SetupWithStoreMock(t)
|
||||
defer th.TearDown()
|
||||
|
||||
web := New(th.Server)
|
||||
handler := web.NewHandler(handlerForServeDefaultSecurityHeaders)
|
||||
|
||||
paths := []string{
|
||||
"/api/v4/test", // API
|
||||
"/static/manifest.json", // this should always exist. Static files have their own handler
|
||||
// Note that the plugin handler isn't tested, also plugins may support arbitrary functionality
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
request := httptest.NewRequest("GET", path, nil)
|
||||
|
||||
response := httptest.NewRecorder()
|
||||
handler.ServeHTTP(response, request)
|
||||
|
||||
// header.Get returns a "" also if the header doesn't exist so we check that there is at least
|
||||
// one Permissions-Policy header and their value is "". We check with .Values() as it canonicalizes
|
||||
// the key.
|
||||
permissionsPolicyHeader := response.Header().Get("Permissions-Policy")
|
||||
permissionsPolicyHeaderValues := response.Header().Values("Permissions-Policy")
|
||||
|
||||
contentTypeOptionsHeader := response.Header().Get("X-Content-Type-Options")
|
||||
referrerPolicyHeader := response.Header().Get("Referrer-Policy")
|
||||
|
||||
assert.NotEqualf(t, 0, len(permissionsPolicyHeaderValues), "Permissions-Policy header doesn't exist")
|
||||
assert.Equal(t, "", permissionsPolicyHeader, "Permissions-Policy is not empty")
|
||||
assert.Equal(t, "nosniff", contentTypeOptionsHeader)
|
||||
assert.Equal(t, "no-referrer", referrerPolicyHeader)
|
||||
}
|
||||
}
|
||||
|
||||
func handlerForHTTPSecureTransport(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,11 @@ func staticFilesHandler(handler http.Handler) http.Handler {
|
||||
w.Header().Set("Cache-Control", "max-age=31556926, public")
|
||||
}
|
||||
|
||||
// Hardcoded sensible default values for these security headers. Feel free to override in proxy or ingress
|
||||
w.Header().Set("Permissions-Policy", "")
|
||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
w.Header().Set("Referrer-Policy", "no-referrer")
|
||||
|
||||
if strings.HasSuffix(r.URL.Path, "/") {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
|
||||
Ссылка в новой задаче
Block a user