From 6ad31c4dfeaae72a3d15ac254bc37244d1beae79 Mon Sep 17 00:00:00 2001 From: weizhichen Date: Tue, 26 Mar 2024 07:37:46 +0000 Subject: [PATCH 1/2] fix: strip service account token --- pkg/csi-common/utils.go | 30 +++++++++++++++++++++++++++- pkg/csi-common/utils_test.go | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pkg/csi-common/utils.go b/pkg/csi-common/utils.go index d9536010e..434593a52 100644 --- a/pkg/csi-common/utils.go +++ b/pkg/csi-common/utils.go @@ -17,6 +17,7 @@ limitations under the License. package csicommon import ( + "encoding/json" "fmt" "net" "os" @@ -101,7 +102,7 @@ func getLogLevel(method string) int32 { func LogGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { level := klog.Level(getLogLevel(info.FullMethod)) klog.V(level).Infof("GRPC call: %s", info.FullMethod) - klog.V(level).Infof("GRPC request: %s", protosanitizer.StripSecrets(req)) + klog.V(level).Infof("GRPC request: %s", stripServiceAccountToken(protosanitizer.StripSecrets(req))) resp, err := handler(ctx, req) if err != nil { @@ -111,3 +112,30 @@ func LogGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, h } return resp, err } + +func stripServiceAccountToken(req fmt.Stringer) string { + var parsed map[string]interface{} + + err := json.Unmarshal([]byte(req.String()), &parsed) + if err != nil || parsed == nil { + return req.String() + } + + volumeContext, ok := parsed["volume_context"].(map[string]interface{}) + if !ok { + return req.String() + } + + if _, ok := volumeContext["csi.storage.k8s.io/serviceAccount.tokens"]; !ok { + return req.String() + } + + volumeContext["csi.storage.k8s.io/serviceAccount.tokens"] = "***stripped***" + + b, err := json.Marshal(parsed) + if err != nil { + return req.String() + } + + return string(b) +} diff --git a/pkg/csi-common/utils_test.go b/pkg/csi-common/utils_test.go index 8a75286c5..04a8f18ce 100644 --- a/pkg/csi-common/utils_test.go +++ b/pkg/csi-common/utils_test.go @@ -119,6 +119,44 @@ func TestLogGRPC(t *testing.T) { }, `GRPC request: {"starting_token":"testtoken"}`, }, + { + "NodeStageVolumeRequest with service account token", + &csi.NodeStageVolumeRequest{ + VolumeContext: map[string]string{ + "csi.storage.k8s.io/serviceAccount.tokens": "testtoken", + "csi.storage.k8s.io/testfield": "testvalue", + }, + XXX_sizecache: 100, + }, + `GRPC request: {"volume_context":{"csi.storage.k8s.io/serviceAccount.tokens":"***stripped***","csi.storage.k8s.io/testfield":"testvalue"}}`, + }, + { + "NodePublishVolumeRequest with service account token", + &csi.NodePublishVolumeRequest{ + VolumeContext: map[string]string{ + "csi.storage.k8s.io/serviceAccount.tokens": "testtoken", + "csi.storage.k8s.io/testfield": "testvalue", + }, + XXX_sizecache: 100, + }, + `GRPC request: {"volume_context":{"csi.storage.k8s.io/serviceAccount.tokens":"***stripped***","csi.storage.k8s.io/testfield":"testvalue"}}`, + }, + { + "with secrets and service account token", + &csi.NodeStageVolumeRequest{ + VolumeId: "vol_1", + Secrets: map[string]string{ + "account_name": "k8s", + "account_key": "testkey", + }, + VolumeContext: map[string]string{ + "csi.storage.k8s.io/serviceAccount.tokens": "testtoken", + "csi.storage.k8s.io/testfield": "testvalue", + }, + XXX_sizecache: 100, + }, + `GRPC request: {"secrets":"***stripped***","volume_context":{"csi.storage.k8s.io/serviceAccount.tokens":"***stripped***","csi.storage.k8s.io/testfield":"testvalue"},"volume_id":"vol_1"}`, + }, } for _, test := range tests { From 6c657d4fe8183e72c8fa65758a33c2277ab94517 Mon Sep 17 00:00:00 2001 From: weizhichen Date: Tue, 26 Mar 2024 08:47:00 +0000 Subject: [PATCH 2/2] make function more general --- pkg/csi-common/utils.go | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/pkg/csi-common/utils.go b/pkg/csi-common/utils.go index 434593a52..957a26fc7 100644 --- a/pkg/csi-common/utils.go +++ b/pkg/csi-common/utils.go @@ -102,7 +102,7 @@ func getLogLevel(method string) int32 { func LogGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { level := klog.Level(getLogLevel(info.FullMethod)) klog.V(level).Infof("GRPC call: %s", info.FullMethod) - klog.V(level).Infof("GRPC request: %s", stripServiceAccountToken(protosanitizer.StripSecrets(req))) + klog.V(level).Infof("GRPC request: %s", StripSensitiveValue(protosanitizer.StripSecrets(req), "csi.storage.k8s.io/serviceAccount.tokens")) resp, err := handler(ctx, req) if err != nil { @@ -113,7 +113,25 @@ func LogGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, h return resp, err } -func stripServiceAccountToken(req fmt.Stringer) string { +type stripSensitiveValue struct { + // volume_context[key] is the value to be stripped. + key string + // req is the csi grpc request stripped by `protosanitizer.StripSecrets` + req fmt.Stringer +} + +func StripSensitiveValue(req fmt.Stringer, key string) fmt.Stringer { + return &stripSensitiveValue{ + key: key, + req: req, + } +} + +func (s *stripSensitiveValue) String() string { + return stripSensitiveValueByKey(s.req, s.key) +} + +func stripSensitiveValueByKey(req fmt.Stringer, key string) string { var parsed map[string]interface{} err := json.Unmarshal([]byte(req.String()), &parsed) @@ -126,11 +144,11 @@ func stripServiceAccountToken(req fmt.Stringer) string { return req.String() } - if _, ok := volumeContext["csi.storage.k8s.io/serviceAccount.tokens"]; !ok { + if _, ok := volumeContext[key]; !ok { return req.String() } - volumeContext["csi.storage.k8s.io/serviceAccount.tokens"] = "***stripped***" + volumeContext[key] = "***stripped***" b, err := json.Marshal(parsed) if err != nil {