Move X_FRAME_OPTIONS setting from cors to security section (#30256)
## Summary - Move `cors.X_FRAME_OPTIONS` to `security.X_FRAME_OPTIONS` (old location still works with a deprecation warning) - Support `"unset"` as a special value to remove the `X-Frame-Options` header entirely - Remove `X-Frame-Options` header from API responses (only set for web/HTML responses) ## Migration If you had customized `cors.X_FRAME_OPTIONS`, move it to the `[security]` section. The old location is deprecated and will be removed in a future release. --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -521,6 +521,9 @@ INTERNAL_TOKEN =
|
|||||||
;; Set the two-factor auth behavior.
|
;; Set the two-factor auth behavior.
|
||||||
;; Set to "enforced", to force users to enroll into Two-Factor Authentication, users without 2FA have no access to repositories via API or web.
|
;; Set to "enforced", to force users to enroll into Two-Factor Authentication, users without 2FA have no access to repositories via API or web.
|
||||||
;TWO_FACTOR_AUTH =
|
;TWO_FACTOR_AUTH =
|
||||||
|
;;
|
||||||
|
;; The value of the X-Frame-Options HTTP header for HTML responses. Use "unset" to remove the header.
|
||||||
|
;X_FRAME_OPTIONS = SAMEORIGIN
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@@ -1290,9 +1293,6 @@ LEVEL = Info
|
|||||||
;;
|
;;
|
||||||
;; headers to permit
|
;; headers to permit
|
||||||
;HEADERS = Content-Type,User-Agent
|
;HEADERS = Content-Type,User-Agent
|
||||||
;;
|
|
||||||
;; set X-FRAME-OPTIONS header
|
|
||||||
;X_FRAME_OPTIONS = SAMEORIGIN
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|||||||
@@ -15,13 +15,11 @@ var CORSConfig = struct {
|
|||||||
MaxAge time.Duration
|
MaxAge time.Duration
|
||||||
AllowCredentials bool
|
AllowCredentials bool
|
||||||
Headers []string
|
Headers []string
|
||||||
XFrameOptions string
|
|
||||||
}{
|
}{
|
||||||
AllowDomain: []string{"*"},
|
AllowDomain: []string{"*"},
|
||||||
Methods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
|
Methods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
|
||||||
Headers: []string{"Content-Type", "User-Agent"},
|
Headers: []string{"Content-Type", "User-Agent"},
|
||||||
MaxAge: 10 * time.Minute,
|
MaxAge: 10 * time.Minute,
|
||||||
XFrameOptions: "SAMEORIGIN",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadCorsFrom(rootCfg ConfigProvider) {
|
func loadCorsFrom(rootCfg ConfigProvider) {
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Security settings
|
// Security settings
|
||||||
|
var Security = struct {
|
||||||
|
// TODO: move more settings to this struct in future
|
||||||
|
XFrameOptions string
|
||||||
|
}{
|
||||||
|
XFrameOptions: "SAMEORIGIN",
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
InstallLock bool
|
InstallLock bool
|
||||||
@@ -140,6 +146,13 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
|
|||||||
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
|
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
|
||||||
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)
|
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)
|
||||||
|
|
||||||
|
deprecatedSetting(rootCfg, "cors", "X_FRAME_OPTIONS", "security", "X_FRAME_OPTIONS", "v1.26.0")
|
||||||
|
if sec.HasKey("X_FRAME_OPTIONS") {
|
||||||
|
Security.XFrameOptions = sec.Key("X_FRAME_OPTIONS").MustString(Security.XFrameOptions)
|
||||||
|
} else {
|
||||||
|
Security.XFrameOptions = rootCfg.Section("cors").Key("X_FRAME_OPTIONS").MustString(Security.XFrameOptions)
|
||||||
|
}
|
||||||
|
|
||||||
twoFactorAuth := sec.Key("TWO_FACTOR_AUTH").String()
|
twoFactorAuth := sec.Key("TWO_FACTOR_AUTH").String()
|
||||||
switch twoFactorAuth {
|
switch twoFactorAuth {
|
||||||
case "":
|
case "":
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ func renderServerErrorPage(w http.ResponseWriter, req *http.Request, respCode in
|
|||||||
}
|
}
|
||||||
|
|
||||||
httpcache.SetCacheControlInHeader(w.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
httpcache.SetCacheControlInHeader(w.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
||||||
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
if setting.Security.XFrameOptions != "unset" {
|
||||||
|
w.Header().Set(`X-Frame-Options`, setting.Security.XFrameOptions)
|
||||||
|
}
|
||||||
|
|
||||||
tmplCtx := context.NewTemplateContext(req.Context(), req)
|
tmplCtx := context.NewTemplateContext(req.Context(), req)
|
||||||
tmplCtx["Locale"] = middleware.Locale(w, req)
|
tmplCtx["Locale"] = middleware.Locale(w, req)
|
||||||
|
|||||||
@@ -235,8 +235,6 @@ func APIContexter() func(http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
||||||
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
|
||||||
|
|
||||||
next.ServeHTTP(ctx.Resp, ctx.Req)
|
next.ServeHTTP(ctx.Resp, ctx.Req)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,7 +196,10 @@ func Contexter() func(next http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
httpcache.SetCacheControlInHeader(ctx.Resp.Header(), &httpcache.CacheControlOptions{NoTransform: true})
|
||||||
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
|
||||||
|
if setting.Security.XFrameOptions != "unset" {
|
||||||
|
ctx.Resp.Header().Set(`X-Frame-Options`, setting.Security.XFrameOptions)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["SystemConfig"] = setting.Config()
|
ctx.Data["SystemConfig"] = setting.Config()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user