Skip to content

Move cors.X_FRAME_OPTIONS to security.X_FRAME_OPTIONS and add false option #30256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,9 @@ INTERNAL_TOKEN =
;; stemming from cached/logged plain-text API tokens.
;; In future releases, this will become the default behavior
;DISABLE_QUERY_AUTH_TOKEN = false
;;
;; The value of the X-FRAME-OPTIONS header for HTML and API requests. Set to "false" to remove the header.
;X_FRAME_OPTIONS = SAMEORIGIN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down Expand Up @@ -1187,9 +1190,6 @@ LEVEL = Info
;;
;; headers to permit
;HEADERS = Content-Type,User-Agent
;;
;; set X-FRAME-OPTIONS header
;X_FRAME_OPTIONS = SAMEORIGIN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
2 changes: 1 addition & 1 deletion docs/content/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `MAX_AGE`: **10m**: max time to cache response
- `ALLOW_CREDENTIALS`: **false**: allow request with credentials
- `HEADERS`: **Content-Type,User-Agent**: additional headers that are permitted in requests
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: Set the `X-Frame-Options` header value.

## UI (`ui`)

Expand Down Expand Up @@ -584,6 +583,7 @@ And the following unique queues:
- `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed.
- `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security.
- `DISABLE_QUERY_AUTH_TOKEN`: **false**: Reject API tokens sent in URL query string (Accept Header-based API tokens only). This setting will default to `true` in Gitea 1.23 and be deprecated in Gitea 1.24.
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: The value of the X-FRAME-OPTIONS header for HTML and API requests. Set to `false to remove the header.

## Camo (`camo`)

Expand Down
2 changes: 1 addition & 1 deletion docs/content/administration/config-cheat-sheet.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ menu:
- `MAX_AGE`: **10m**: 缓存响应的最大时间
- `ALLOW_CREDENTIALS`: **false**: 允许带有凭据的请求
- `HEADERS`: **Content-Type,User-Agent**: 允许请求携带的头部
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: 详见 `X-Frame-Options`HTTP头部.

## 界面 (`ui`)

Expand Down Expand Up @@ -552,6 +551,7 @@ Gitea 创建以下非唯一队列:
- off - 不检查密码复杂性
- `PASSWORD_CHECK_PWN`: **false**:检查密码是否在 [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) 中曝光。
- `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**:缓存成功的令牌哈希。API 令牌在数据库中存储为 pbkdf2 哈希,但这意味着在存在多个 API 操作时可能会有显着的哈希负载。此缓存将在 LRU 缓存中存储成功的哈希令牌,以在性能和安全性之间保持平衡。
- `X_FRAME_OPTIONS`: **SAMEORIGIN**: HTML 和 API 请求的 X-FRAME-OPTIONS 标头的值。 设置为`false`以删除标头。

## Camo (`camo`)

Expand Down
10 changes: 4 additions & 6 deletions modules/setting/cors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ var CORSConfig = struct {
MaxAge time.Duration
AllowCredentials bool
Headers []string
XFrameOptions string
}{
AllowDomain: []string{"*"},
Methods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
Headers: []string{"Content-Type", "User-Agent"},
MaxAge: 10 * time.Minute,
XFrameOptions: "SAMEORIGIN",
AllowDomain: []string{"*"},
Methods: []string{"GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
Headers: []string{"Content-Type", "User-Agent"},
MaxAge: 10 * time.Minute,
}

func loadCorsFrom(rootCfg ConfigProvider) {
Expand Down
5 changes: 5 additions & 0 deletions modules/setting/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ var (
DisableQueryAuthToken bool
CSRFCookieName = "_csrf"
CSRFCookieHTTPOnly = true
XFrameOptions string
UseXFrameOptions bool
)

// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set
Expand Down Expand Up @@ -140,6 +142,9 @@ func loadSecurityFrom(rootCfg ConfigProvider) {
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false)
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20)

XFrameOptions = sec.Key("X_FRAME_OPTIONS").MustString("SAMEORIGIN")
UseXFrameOptions = XFrameOptions != "false"

InternalToken = loadSecret(sec, "INTERNAL_TOKEN_URI", "INTERNAL_TOKEN")
if InstallLock && InternalToken == "" {
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate
Expand Down
5 changes: 4 additions & 1 deletion routers/common/errpage.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
routing.UpdatePanicError(req.Context(), err)

httpcache.SetCacheControlInHeader(w.Header(), 0, "no-transform")
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)

if setting.UseXFrameOptions {
w.Header().Set(`X-Frame-Options`, setting.XFrameOptions)
}

tmplCtx := context.TemplateContext{}
tmplCtx["Locale"] = middleware.Locale(w, req)
Expand Down
5 changes: 4 additions & 1 deletion services/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,10 @@ func APIContexter() func(http.Handler) http.Handler {
}

httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)

if setting.UseXFrameOptions {
ctx.Resp.Header().Set(`X-Frame-Options`, setting.XFrameOptions)
}

next.ServeHTTP(ctx.Resp, ctx.Req)
})
Expand Down
5 changes: 4 additions & 1 deletion services/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ func Contexter() func(next http.Handler) http.Handler {
}

httpcache.SetCacheControlInHeader(ctx.Resp.Header(), 0, "no-transform")
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)

if setting.UseXFrameOptions {
ctx.Resp.Header().Set(`X-Frame-Options`, setting.XFrameOptions)
}

ctx.Data["SystemConfig"] = setting.Config()
ctx.Data["CsrfToken"] = ctx.Csrf.GetToken()
Expand Down