Prevent anonymous container access if RequireSignInView is enabled (#28877)

Fixes #28875

If `RequireSignInView` is enabled, the ghost user has no access rights.
This commit is contained in:
KN4CK3R 2024-01-21 17:31:29 +01:00 committed by GitHub
parent b693611b35
commit caad931385
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 6 deletions

View file

@ -93,7 +93,7 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any))
} }
func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.AccessMode, error) { func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.AccessMode, error) {
if setting.Service.RequireSignInView && doer == nil { if setting.Service.RequireSignInView && (doer == nil || doer.IsGhost()) {
return perm.AccessModeNone, nil return perm.AccessModeNone, nil
} }

View file

@ -114,11 +114,15 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
}) })
} }
// ReqContainerAccess is a middleware which checks the current user valid (real user or ghost for anonymous access) func apiUnauthorizedError(ctx *context.Context) {
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token",service="container_registry",scope="*"`)
apiErrorDefined(ctx, errUnauthorized)
}
// ReqContainerAccess is a middleware which checks the current user valid (real user or ghost if anonymous access is enabled)
func ReqContainerAccess(ctx *context.Context) { func ReqContainerAccess(ctx *context.Context) {
if ctx.Doer == nil { if ctx.Doer == nil || (setting.Service.RequireSignInView && ctx.Doer.IsGhost()) {
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token",service="container_registry",scope="*"`) apiUnauthorizedError(ctx)
apiErrorDefined(ctx, errUnauthorized)
} }
} }
@ -138,10 +142,15 @@ func DetermineSupport(ctx *context.Context) {
} }
// Authenticate creates a token for the current user // Authenticate creates a token for the current user
// If the current user is anonymous, the ghost user is used // If the current user is anonymous, the ghost user is used unless RequireSignInView is enabled.
func Authenticate(ctx *context.Context) { func Authenticate(ctx *context.Context) {
u := ctx.Doer u := ctx.Doer
if u == nil { if u == nil {
if setting.Service.RequireSignInView {
apiUnauthorizedError(ctx)
return
}
u = user_model.NewGhostUser() u = user_model.NewGhostUser()
} }

View file

@ -21,6 +21,7 @@ import (
container_module "code.gitea.io/gitea/modules/packages/container" container_module "code.gitea.io/gitea/modules/packages/container"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/minio/sha256-simd" "github.com/minio/sha256-simd"
@ -106,6 +107,14 @@ func TestPackageContainer(t *testing.T) {
req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)).
AddTokenAuth(anonymousToken) AddTokenAuth(anonymousToken)
MakeRequest(t, req, http.StatusOK) MakeRequest(t, req, http.StatusOK)
defer test.MockVariableValue(&setting.Service.RequireSignInView, true)()
req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL))
MakeRequest(t, req, http.StatusUnauthorized)
req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL))
MakeRequest(t, req, http.StatusUnauthorized)
}) })
t.Run("User", func(t *testing.T) { t.Run("User", func(t *testing.T) {