fix: config Set/Get decrypt/encrypt using authenticated credentials (#9447)

we have policy available for sub-admin users to set/get/delete
config, but we incorrectly decrypt the content using admin secret
key which in-fact should be the credential authenticating the
request.
This commit is contained in:
Harshavardhana 2020-04-24 22:36:48 -07:00 committed by GitHub
parent 60d415bb8a
commit 558785a4bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -35,33 +35,34 @@ import (
"github.com/minio/minio/cmd/config/storageclass" "github.com/minio/minio/cmd/config/storageclass"
"github.com/minio/minio/cmd/crypto" "github.com/minio/minio/cmd/crypto"
"github.com/minio/minio/cmd/logger" "github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/auth"
iampolicy "github.com/minio/minio/pkg/iam/policy" iampolicy "github.com/minio/minio/pkg/iam/policy"
"github.com/minio/minio/pkg/madmin" "github.com/minio/minio/pkg/madmin"
) )
func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) ObjectLayer { func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) (auth.Credentials, ObjectLayer) {
// Get current object layer instance. // Get current object layer instance.
objectAPI := newObjectLayerWithoutSafeModeFn() objectAPI := newObjectLayerWithoutSafeModeFn()
if objectAPI == nil { if objectAPI == nil {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
return nil return auth.Credentials{}, nil
} }
// Validate request signature. // Validate request signature.
_, adminAPIErr := checkAdminRequestAuthType(ctx, r, iampolicy.ConfigUpdateAdminAction, "") cred, adminAPIErr := checkAdminRequestAuthType(ctx, r, iampolicy.ConfigUpdateAdminAction, "")
if adminAPIErr != ErrNone { if adminAPIErr != ErrNone {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL)
return nil return cred, nil
} }
return objectAPI return cred, objectAPI
} }
// DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv // DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv
func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "DelConfigKVHandler") ctx := newContext(r, w, "DelConfigKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -72,7 +73,7 @@ func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Requ
return return
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
if err != nil { if err != nil {
logger.LogIf(ctx, err, logger.Application) logger.LogIf(ctx, err, logger.Application)
@ -101,7 +102,7 @@ func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Requ
func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "SetConfigKVHandler") ctx := newContext(r, w, "SetConfigKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -112,7 +113,7 @@ func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Requ
return return
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
if err != nil { if err != nil {
logger.LogIf(ctx, err, logger.Application) logger.LogIf(ctx, err, logger.Application)
@ -160,7 +161,7 @@ func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Requ
func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetConfigKVHandler") ctx := newContext(r, w, "GetConfigKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -183,7 +184,7 @@ func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Requ
return return
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
econfigData, err := madmin.EncryptData(password, buf.Bytes()) econfigData, err := madmin.EncryptData(password, buf.Bytes())
if err != nil { if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
@ -196,7 +197,7 @@ func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Requ
func (a adminAPIHandlers) ClearConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) ClearConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ClearConfigHistoryKVHandler") ctx := newContext(r, w, "ClearConfigHistoryKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) _, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -231,7 +232,7 @@ func (a adminAPIHandlers) ClearConfigHistoryKVHandler(w http.ResponseWriter, r *
func (a adminAPIHandlers) RestoreConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) RestoreConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "RestoreConfigHistoryKVHandler") ctx := newContext(r, w, "RestoreConfigHistoryKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) _, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -277,7 +278,7 @@ func (a adminAPIHandlers) RestoreConfigHistoryKVHandler(w http.ResponseWriter, r
func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "ListConfigHistoryKVHandler") ctx := newContext(r, w, "ListConfigHistoryKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -301,7 +302,7 @@ func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *h
return return
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
econfigData, err := madmin.EncryptData(password, data) econfigData, err := madmin.EncryptData(password, data)
if err != nil { if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
@ -315,7 +316,7 @@ func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *h
func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "HelpConfigKVHandler") ctx := newContext(r, w, "HelpConfigKVHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) _, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -341,7 +342,7 @@ func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Req
func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "SetConfigHandler") ctx := newContext(r, w, "SetConfigHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -352,7 +353,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
return return
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) kvBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
if err != nil { if err != nil {
logger.LogIf(ctx, err, logger.Application) logger.LogIf(ctx, err, logger.Application)
@ -396,7 +397,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Request) { func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "GetConfigHandler") ctx := newContext(r, w, "GetConfigHandler")
objectAPI := validateAdminReqConfigKV(ctx, w, r) cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
if objectAPI == nil { if objectAPI == nil {
return return
} }
@ -453,7 +454,7 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques
} }
} }
password := globalActiveCred.SecretKey password := cred.SecretKey
econfigData, err := madmin.EncryptData(password, []byte(s.String())) econfigData, err := madmin.EncryptData(password, []byte(s.String()))
if err != nil { if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)