Skip to content

Commit 49c6736

Browse files
committed
Clear secrets from request for klog print in logGRPC()
Malicious user can put a secret in request as explained here: kubernetes-sigs#1372.
1 parent 450be4d commit 49c6736

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

pkg/gce-pd-csi-driver/utils.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"errors"
2222
"fmt"
23+
"reflect"
2324

2425
csi "github.com/container-storage-interface/spec/lib/go/csi"
2526
"google.golang.org/grpc"
@@ -59,14 +60,30 @@ func NewNodeServiceCapability(cap csi.NodeServiceCapability_RPC_Type) *csi.NodeS
5960
}
6061
}
6162

63+
// Reflect magic below simply clears Secrets map from request.
64+
func clearSecrets(req interface{}) interface{} {
65+
v := reflect.ValueOf(&req).Elem()
66+
e := reflect.New(v.Elem().Type()).Elem()
67+
e.Set(v.Elem())
68+
f := reflect.Indirect(e).FieldByName("Secrets")
69+
if f.IsValid() && f.CanSet() && f.Kind() == reflect.Map {
70+
f.Set(reflect.MakeMap(f.Type()))
71+
v.Set(e)
72+
}
73+
return req
74+
}
75+
6276
func logGRPC(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
6377
if info.FullMethod == ProbeCSIFullMethod {
6478
return handler(ctx, req)
6579
}
66-
// Note that secrets are not included in any RPC message. In the past protosanitizer and other log
80+
// Note that secrets may be included in some RPC messages
81+
// (https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/issues/1372),
82+
// but the driver ignores them. In the past protosanitizer and other log
6783
// stripping was shown to cause a significant increase of CPU usage (see
6884
// https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/issues/356#issuecomment-550529004).
69-
klog.V(4).Infof("%s called with request: %s", info.FullMethod, req)
85+
// That is why we use hand-crafted clearSecrets() below rather than protosanitizer.
86+
klog.V(4).Infof("%s called with request: %s", info.FullMethod, clearSecrets(req))
7087
resp, err := handler(ctx, req)
7188
if err != nil {
7289
klog.Errorf("%s returned with error: %v", info.FullMethod, err.Error())

pkg/gce-pd-csi-driver/utils_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ limitations under the License.
1818
package gceGCEDriver
1919

2020
import (
21+
"context"
2122
"fmt"
23+
"reflect"
2224
"testing"
2325

2426
csi "github.com/container-storage-interface/spec/lib/go/csi"
2527
"github.com/google/go-cmp/cmp"
28+
"google.golang.org/grpc"
2629
"sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/common"
2730
)
2831

@@ -723,3 +726,53 @@ func TestValidateStoragePoolZones(t *testing.T) {
723726
}
724727
}
725728
}
729+
730+
func TestClearSecrets(t *testing.T) {
731+
vc := &csi.VolumeCapability{
732+
AccessType: &csi.VolumeCapability_Mount{
733+
Mount: &csi.VolumeCapability_MountVolume{},
734+
},
735+
AccessMode: &csi.VolumeCapability_AccessMode{
736+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
737+
},
738+
}
739+
740+
req := &csi.NodeExpandVolumeRequest{
741+
VolumePath: "/path",
742+
VolumeCapability: vc,
743+
Secrets: map[string]string{
744+
"key": "value",
745+
},
746+
}
747+
748+
clearedReq := &csi.NodeExpandVolumeRequest{
749+
VolumePath: "/path",
750+
VolumeCapability: vc,
751+
Secrets: map[string]string{},
752+
}
753+
754+
if !reflect.DeepEqual(clearSecrets(req), clearedReq) {
755+
t.Fatalf("Unexpected change: %v vs. %v", clearSecrets(req), clearedReq)
756+
}
757+
}
758+
759+
func TestLogGRPC(t *testing.T) {
760+
info := &grpc.UnaryServerInfo{
761+
FullMethod: "foo",
762+
}
763+
764+
req := struct {
765+
Secrets map[string]string
766+
}{map[string]string{
767+
"password": "pass",
768+
}}
769+
770+
handler := func(ctx context.Context, req any) (any, error) {
771+
return nil, nil
772+
}
773+
774+
_, err := logGRPC(nil, req, info, handler)
775+
if err != nil {
776+
t.Fatalf("logGRPC returns error %v", err)
777+
}
778+
}

0 commit comments

Comments
 (0)