From 7c04846eacf69f31f442d507625de2d1c35d0a5f Mon Sep 17 00:00:00 2001 From: Andrew Lytvynov Date: Wed, 19 Jul 2023 11:58:29 -0700 Subject: [PATCH] tsweb: relax CSP for debug handlers (#8649) Allow inline CSS for debug handlers to make prototyping easier. These are generally not accessible to the public and the small risk of CSS injection via user content seems acceptable. Also allow form submissions on the same domain, instead of banning all forms. An example of such form is http://webhooks.corp.ts.net:6359/debug/private-nodes/ Updates #3576 Signed-off-by: Andrew Lytvynov --- tsweb/debug.go | 16 +++++++++++++++- tsweb/tsweb.go | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tsweb/debug.go b/tsweb/debug.go index 92475aeef..0891784c2 100644 --- a/tsweb/debug.go +++ b/tsweb/debug.go @@ -98,7 +98,7 @@ func (d *DebugHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // entry in /debug/ for it. func (d *DebugHandler) Handle(slug, desc string, handler http.Handler) { href := "/debug/" + slug - d.mux.Handle(href, Protected(BrowserHeaderHandler(handler))) + d.mux.Handle(href, Protected(debugBrowserHeaderHandler(handler))) d.URL(href, desc) } @@ -141,3 +141,17 @@ func gcHandler(w http.ResponseWriter, r *http.Request) { runtime.GC() w.Write([]byte("Done.\n")) } + +// debugBrowserHeaderHandler is a wrapper around BrowserHeaderHandler with a +// more relaxed Content-Security-Policy that's acceptable for internal debug +// pages. It should not be used on any public-facing handlers! +func debugBrowserHeaderHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + AddBrowserHeaders(w) + // The only difference from AddBrowserHeaders is that this policy + // allows inline CSS styles. They make debug pages much easier to + // prototype, while the risk of user-injected CSS is relatively low. + w.Header().Set("Content-Security-Policy", "default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; block-all-mixed-content; plugin-types 'none'; style-src 'self' 'unsafe-inline'") + h.ServeHTTP(w, r) + }) +} diff --git a/tsweb/tsweb.go b/tsweb/tsweb.go index d01e8b7e0..c4e042aa1 100644 --- a/tsweb/tsweb.go +++ b/tsweb/tsweb.go @@ -435,7 +435,7 @@ func VarzHandler(w http.ResponseWriter, r *http.Request) { // https://infosec.mozilla.org/guidelines/web_security func AddBrowserHeaders(w http.ResponseWriter) { w.Header().Set("Strict-Transport-Security", "max-age=63072000; includeSubDomains") - w.Header().Set("Content-Security-Policy", "default-src 'self'; frame-ancestors 'none'; form-action 'none'; base-uri 'self'; block-all-mixed-content; plugin-types 'none'") + w.Header().Set("Content-Security-Policy", "default-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; block-all-mixed-content; plugin-types 'none'") w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("X-Content-Type-Options", "nosniff") }