From 8d52c7daf3db9d7e33bf6d50daa39789a4af46a3 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 9 Oct 2021 22:00:23 -0700 Subject: [PATCH] fix: disallow invalid x-amz-security-token for root credentials (#13388) * fix: disallow invalid x-amz-security-token for root credentials fixes #13335 This was a regression added in #12947 when this part of the code was refactored to avoid privilege issues with service accounts with session policy. Bonus: - fix: AssumeRoleWithCertificate policy mapping and reload AssumeRoleWithCertificate was not mapping to correct policies even after successfully generating keys, since the claims associated with this API were never looked up properly. Ensure that policies are set appropriately. - GetUser() API was not loading policies correctly based on AccessKey based mapping which is true with OpenID and AssumeRoleWithCertificate API. --- cmd/iam.go | 2 +- cmd/signature-v4-utils.go | 29 ++++++++++++++++++----------- cmd/sts-handlers.go | 11 ++++++----- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/cmd/iam.go b/cmd/iam.go index 6a1a54721..d4758c7a8 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -1817,7 +1817,7 @@ func (sys *IAMSys) GetUser(accessKey string) (cred auth.Credentials, ok bool) { if ok && cred.IsValid() { if cred.IsServiceAccount() || cred.IsTemp() { - policies, err := sys.policyDBGet(cred.ParentUser, false) + policies, err := sys.policyDBGet(cred.AccessKey, false) if err != nil { // Reject if the policy map for user doesn't exist anymore. logger.LogIf(context.Background(), fmt.Errorf("'%s' user does not have a policy present", cred.ParentUser)) diff --git a/cmd/signature-v4-utils.go b/cmd/signature-v4-utils.go index e74d4428e..b28a38020 100644 --- a/cmd/signature-v4-utils.go +++ b/cmd/signature-v4-utils.go @@ -149,6 +149,7 @@ func checkKeyValid(r *http.Request, accessKey string) (auth.Credentials, bool, A // to retry with 503 errors when server is coming up. return auth.Credentials{}, false, ErrServerNotInitialized } + var owner = true var cred = globalActiveCred if cred.AccessKey != accessKey { @@ -157,19 +158,25 @@ func checkKeyValid(r *http.Request, accessKey string) (auth.Credentials, bool, A if !ok { return cred, false, ErrInvalidAccessKeyID } - claims, s3Err := checkClaimsFromToken(r, ucred) - if s3Err != ErrNone { - return cred, false, s3Err - } - ucred.Claims = claims - // Now check if we have a sessionPolicy. - if _, ok = claims[iampolicy.SessionPolicyName]; ok { - owner = false - } else { - owner = cred.AccessKey == ucred.ParentUser - } cred = ucred } + + claims, s3Err := checkClaimsFromToken(r, cred) + if s3Err != ErrNone { + return cred, false, s3Err + } + + if len(claims) > 0 { + cred.Claims = claims + + // Now check if we have a sessionPolicy. + if _, ok := claims[iampolicy.SessionPolicyName]; ok { + owner = false + } else { + owner = cred.AccessKey == cred.ParentUser + } + } + return cred, owner, ErrNone } diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index cc225d8b7..ecc6135fb 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -767,11 +767,12 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h parentUser := "tls:" + certificate.Subject.CommonName tmpCredentials, err := auth.GetNewCredentialsWithMetadata(map[string]interface{}{ - expClaim: time.Now().UTC().Add(expiry).Unix(), - parentClaim: parentUser, - subClaim: certificate.Subject.CommonName, - audClaim: certificate.Subject.Organization, - issClaim: certificate.Issuer.CommonName, + expClaim: time.Now().UTC().Add(expiry).Unix(), + parentClaim: parentUser, + subClaim: certificate.Subject.CommonName, + audClaim: certificate.Subject.Organization, + issClaim: certificate.Issuer.CommonName, + iamPolicyClaimNameOpenID(): certificate.Subject.CommonName, }, globalActiveCred.SecretKey) if err != nil { writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)