From d6dd17a483a839d4e4a2aada52a497f1da291d4a Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 26 Jan 2022 21:53:36 -0800 Subject: [PATCH] make sure to pass groups for all credentials while verifying policies (#14193) fixes #14180 --- cmd/bucket-handlers.go | 1 + cmd/jwt.go | 17 ++++++++++------- cmd/jwt_test.go | 2 +- cmd/metrics.go | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/cmd/bucket-handlers.go b/cmd/bucket-handlers.go index 24f72292a..7754741cb 100644 --- a/cmd/bucket-handlers.go +++ b/cmd/bucket-handlers.go @@ -951,6 +951,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h // explicit permissions for the user. if !globalIAMSys.IsAllowed(iampolicy.Args{ AccountName: cred.AccessKey, + Groups: cred.Groups, Action: iampolicy.PutObjectAction, ConditionValues: getConditionValues(r, "", cred.AccessKey, cred.Claims), BucketName: bucket, diff --git a/cmd/jwt.go b/cmd/jwt.go index 288a3cb37..f2b18d19f 100644 --- a/cmd/jwt.go +++ b/cmd/jwt.go @@ -132,13 +132,13 @@ func authenticateURL(accessKey, secretKey string) (string, error) { // Check if the request is authenticated. // Returns nil if the request is authenticated. errNoAuthToken if token missing. // Returns errAuthentication for all other errors. -func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) { +func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, []string, bool, error) { token, err := jwtreq.AuthorizationHeaderExtractor.ExtractToken(req) if err != nil { if err == jwtreq.ErrNoTokenInRequest { - return nil, false, errNoAuthToken + return nil, nil, false, errNoAuthToken } - return nil, false, err + return nil, nil, false, err } claims := xjwt.NewMapClaims() if err := xjwt.ParseWithClaims(token, claims, func(claims *xjwt.MapClaims) ([]byte, error) { @@ -151,20 +151,21 @@ func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) { } return []byte(cred.SecretKey), nil }); err != nil { - return claims, false, errAuthentication + return claims, nil, false, errAuthentication } owner := true + var groups []string if globalActiveCred.AccessKey != claims.AccessKey { // Check if the access key is part of users credentials. ucred, ok := globalIAMSys.GetUser(req.Context(), claims.AccessKey) if !ok { - return nil, false, errInvalidAccessKeyID + return nil, nil, false, errInvalidAccessKeyID } // get embedded claims eclaims, s3Err := checkClaimsFromToken(req, ucred) if s3Err != ErrNone { - return nil, false, errAuthentication + return nil, nil, false, errAuthentication } for k, v := range eclaims { @@ -177,9 +178,11 @@ func webRequestAuthenticate(req *http.Request) (*xjwt.MapClaims, bool, error) { } else { owner = globalActiveCred.AccessKey == ucred.ParentUser } + + groups = ucred.Groups } - return claims, owner, nil + return claims, groups, owner, nil } // newCachedAuthToken returns a token that is cached up to 15 seconds. diff --git a/cmd/jwt_test.go b/cmd/jwt_test.go index b7f10476e..8a6b09be2 100644 --- a/cmd/jwt_test.go +++ b/cmd/jwt_test.go @@ -149,7 +149,7 @@ func TestWebRequestAuthenticate(t *testing.T) { } for i, testCase := range testCases { - _, _, gotErr := webRequestAuthenticate(testCase.req) + _, _, _, gotErr := webRequestAuthenticate(testCase.req) if testCase.expectedErr != gotErr { t.Errorf("Test %d, expected err %s, got %s", i+1, testCase.expectedErr, gotErr) } diff --git a/cmd/metrics.go b/cmd/metrics.go index dc7956dbf..e626eddaa 100644 --- a/cmd/metrics.go +++ b/cmd/metrics.go @@ -674,7 +674,7 @@ func metricsHandler() http.Handler { // AuthMiddleware checks if the bearer token is valid and authorized. func AuthMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - claims, owner, authErr := webRequestAuthenticate(r) + claims, groups, owner, authErr := webRequestAuthenticate(r) if authErr != nil || !claims.VerifyIssuer("prometheus", true) { w.WriteHeader(http.StatusForbidden) return @@ -682,6 +682,7 @@ func AuthMiddleware(h http.Handler) http.Handler { // For authenticated users apply IAM policy. if !globalIAMSys.IsAllowed(iampolicy.Args{ AccountName: claims.AccessKey, + Groups: groups, Action: iampolicy.PrometheusAdminAction, ConditionValues: getConditionValues(r, "", claims.AccessKey, claims.Map()), IsOwner: owner,