From 29550287767f050733d31c92350615416572c787 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Mon, 15 Jan 2018 11:13:52 -0800 Subject: [PATCH 1/2] add a couple HTTP response headers --- libpages/server.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/libpages/server.go b/libpages/server.go index 0a95a8f5f5..5791517fd7 100644 --- a/libpages/server.go +++ b/libpages/server.go @@ -287,6 +287,27 @@ func (s *Server) logRequest(sri *ServedRequestInfo, requestPath string) { ) } +func (s *Server) setCommonResponseHeaders(w http.ResponseWriter) { + // Since http.FileServer already sets MIME type properly, disable MIME type + // sniffing on browser-side. This would prevent e.g. an attack where a + // malicious html file with .jpg suffix being executed by browser without + // site visitors' awareness. References: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + // https://helmetjs.github.io/docs/dont-sniff-mimetype/ + w.Header().Set("X-Content-Type-Options", "nosniff") + // Enforce XSS protection. References: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + // https://blog.innerht.ml/the-misunderstood-x-xss-protection/ + w.Header().Set("X-XSS-Protection", "1; mode=block") + // Only allow HTTPS on this domain, and make this policy it expire in a + // week. This means if user decides to migrate off Keybase Pages, there's a + // 1-week gap before they can use HTTP again. Note that we don't use the + // 'preload' directive, for the same reason we use 302 instead of 301 for + // HTTP->HTTPS redirection. Reference: https://hstspreload.org/#opt-in + w.Header().Set("Strict-Transport-Security", "max-age=604800; includeSubDomains") + // TODO: allow user to opt-in some directives of Content-Security-Policy? +} + // ServeHTTP implements the http.Handler interface. func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { sri := &ServedRequestInfo{ @@ -301,12 +322,13 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { } defer s.logRequest(sri, r.URL.Path) + s.setCommonResponseHeaders(w) + // Don't serve the config file itself. if path.Clean(strings.ToLower(r.URL.Path)) == config.DefaultConfigFilepath { // TODO: integrate this check into Config? - w.WriteHeader(http.StatusForbidden) - fmt.Fprintf(w, "Reading %s directly is forbidden.", - config.DefaultConfigFilepath) + http.Error(w, fmt.Sprintf("Reading %s directly is forbidden.", + config.DefaultConfigFilepath), http.StatusForbidden) return } @@ -340,6 +362,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { sri.CloningShown = true // TODO: replace this with something nicer when fancy error pages and // landing pages are ready. + w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusServiceUnavailable) w.Write(cloningLandingPage) return From fee3a960854ce1f4bb5d597b7f911f32eef0b2b7 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Mon, 15 Jan 2018 14:42:47 -0800 Subject: [PATCH 2/2] typo fix as suggested by strib and remove nosniff --- libpages/server.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libpages/server.go b/libpages/server.go index 5791517fd7..90646e19f3 100644 --- a/libpages/server.go +++ b/libpages/server.go @@ -288,18 +288,11 @@ func (s *Server) logRequest(sri *ServedRequestInfo, requestPath string) { } func (s *Server) setCommonResponseHeaders(w http.ResponseWriter) { - // Since http.FileServer already sets MIME type properly, disable MIME type - // sniffing on browser-side. This would prevent e.g. an attack where a - // malicious html file with .jpg suffix being executed by browser without - // site visitors' awareness. References: - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options - // https://helmetjs.github.io/docs/dont-sniff-mimetype/ - w.Header().Set("X-Content-Type-Options", "nosniff") // Enforce XSS protection. References: // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection // https://blog.innerht.ml/the-misunderstood-x-xss-protection/ w.Header().Set("X-XSS-Protection", "1; mode=block") - // Only allow HTTPS on this domain, and make this policy it expire in a + // Only allow HTTPS on this domain, and make this policy expire in a // week. This means if user decides to migrate off Keybase Pages, there's a // 1-week gap before they can use HTTP again. Note that we don't use the // 'preload' directive, for the same reason we use 302 instead of 301 for