diff --git a/server/http.go b/server/http.go index c79919f5cf7bebd3f681e99557209dd4710755ee..cd4936cee911c46e819a61b0a520b055f0ef7ce0 100644 --- a/server/http.go +++ b/server/http.go @@ -270,6 +270,8 @@ func (h *Server) handleLogout(w http.ResponseWriter, req *http.Request, session log.Printf("failed to wipe keystore for user %s: %v", session.Username, err) } } + + w.Header().Set("Content-Security-Policy", logoutContentSecurityPolicy) } h.tpl.ExecuteTemplate(w, "logout.html", data) @@ -342,15 +344,21 @@ func (h *Server) Handler() http.Handler { // A relatively strict CSP. const contentSecurityPolicy = "default-src 'none'; img-src 'self' data:; script-src 'self'; style-src 'self'; connect-src 'self';" +// Slightly looser CSP for the logout page: it needs to load remote +// images. +const logoutContentSecurityPolicy = "default-src 'none'; img-src *; script-src 'self'; style-src 'self'; connect-src 'self';" + func withDynamicHeaders(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Pragma", "no-cache") w.Header().Set("Cache-Control", "no-store") w.Header().Set("Expires", "-1") - w.Header().Set("Content-Security-Policy", contentSecurityPolicy) w.Header().Set("X-Frame-Options", "NONE") w.Header().Set("X-XSS-Protection", "1; mode=block") w.Header().Set("X-Content-Type-Options", "nosniff") + if w.Header().Get("Content-Security-Policy") == "" { + w.Header().Set("Content-Security-Policy", contentSecurityPolicy) + } h.ServeHTTP(w, r) }) }