From d2fbdb005d87aad7834d4a2e4cb83b63286a635c Mon Sep 17 00:00:00 2001 From: Will Norris Date: Mon, 11 Dec 2023 19:33:38 -0800 Subject: [PATCH] client/web: use CSP hash for inline javascript Calculate and set the hash of the one inline script we have in index.html. That script is unlikely to change, so hardcoding the hash seems fine for now. Updates #10261 Updates tailscale/corp#16266 Signed-off-by: Will Norris --- client/web/index.html | 5 +++-- client/web/web.go | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/client/web/index.html b/client/web/index.html index e5d889206..8a00d9146 100644 --- a/client/web/index.html +++ b/client/web/index.html @@ -15,13 +15,14 @@ diff --git a/client/web/web.go b/client/web/web.go index a2b9cac40..1cd05a7b7 100644 --- a/client/web/web.go +++ b/client/web/web.go @@ -251,9 +251,13 @@ func (s *Server) serve(w http.ResponseWriter, r *http.Request) { } if !s.devMode { + // This hash corresponds to the inline script in index.html that runs when the react app is unavailable. + // It was generated from https://csplite.com/csp/sha/. + // If the contents of the script are changed, this hash must be updated. + const indexScriptHash = "sha384-CW2AYVfS14P7QHZN27thEkMLKiCj3YNURPoLc1elwiEkMVHeuYTWkJOEki1F3nZc" + w.Header().Set("X-Frame-Options", "DENY") - // TODO: use CSP nonce or hash to eliminate need for unsafe-inline - w.Header().Set("Content-Security-Policy", "default-src 'self'; img-src * data:") + w.Header().Set("Content-Security-Policy", "default-src 'self'; img-src * data:; script-src 'self' '"+indexScriptHash+"'") w.Header().Set("Cross-Origin-Resource-Policy", "same-origin") } }