feat(security): set X-Content-Type-Options: nosniff by default (#37354)
Fixes #37316. --------- Signed-off-by: SAY-5 <SAY-5@users.noreply.github.com> Co-authored-by: SAY-5 <SAY-5@users.noreply.github.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -865,7 +865,6 @@ func checkDeprecatedAuthMethods(ctx *context.APIContext) {
|
||||
func Routes() *web.Router {
|
||||
m := web.NewRouter()
|
||||
|
||||
m.BeforeRouting(securityHeaders())
|
||||
if setting.CORSConfig.Enabled {
|
||||
m.BeforeRouting(cors.Handler(cors.Options{
|
||||
AllowedOrigins: setting.CORSConfig.AllowDomain,
|
||||
@@ -1749,14 +1748,3 @@ func Routes() *web.Router {
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func securityHeaders() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
// CORB: https://www.chromium.org/Home/chromium-security/corb-for-developers
|
||||
// http://stackoverflow.com/a/3146618/244009
|
||||
resp.Header().Set("x-content-type-options", "nosniff")
|
||||
next.ServeHTTP(resp, req)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,6 @@ func renderServerErrorPage(w http.ResponseWriter, req *http.Request, respCode in
|
||||
}
|
||||
|
||||
httpcache.SetCacheControlInHeader(w.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
||||
if setting.Security.XFrameOptions != "unset" {
|
||||
w.Header().Set(`X-Frame-Options`, setting.Security.XFrameOptions)
|
||||
}
|
||||
|
||||
tmplCtx := context.NewTemplateContextForWeb(reqctx.FromContext(req.Context()), req, middleware.Locale(w, req))
|
||||
w.WriteHeader(respCode)
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ func ProtocolMiddlewares() (handlers []any) {
|
||||
// the order is important
|
||||
handlers = append(handlers, ChiRoutePathHandler()) // make sure chi has correct paths
|
||||
handlers = append(handlers, RequestContextHandler()) // prepare the context and panic recovery
|
||||
handlers = append(handlers, SecurityHeadersHandler())
|
||||
|
||||
if setting.ReverseProxyLimit > 0 && len(setting.ReverseProxyTrustedProxies) > 0 {
|
||||
handlers = append(handlers, ForwardedHeadersHandler(setting.ReverseProxyLimit, setting.ReverseProxyTrustedProxies))
|
||||
@@ -48,6 +49,21 @@ func ProtocolMiddlewares() (handlers []any) {
|
||||
return handlers
|
||||
}
|
||||
|
||||
// SecurityHeadersHandler sets headers globally for every response that leaves Gitea.
|
||||
func SecurityHeadersHandler() func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
||||
if setting.Security.XContentTypeOptions != "unset" {
|
||||
resp.Header().Set("X-Content-Type-Options", setting.Security.XContentTypeOptions)
|
||||
}
|
||||
if setting.Security.XFrameOptions != "unset" {
|
||||
resp.Header().Set("X-Frame-Options", setting.Security.XFrameOptions)
|
||||
}
|
||||
next.ServeHTTP(resp, req)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func RequestContextHandler() func(h http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(respOrig http.ResponseWriter, req *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user