Skip to content

Commit

Permalink
Fix redact logic when recuring into list/map fields (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-bxin authored Nov 3, 2023
1 parent 3bbda7c commit 261699c
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 57 deletions.
3 changes: 2 additions & 1 deletion auth/opa/rpcauth/redact.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ func redactNestedField(message protoreflect.Message, descriptor protoreflect.Fie
switch {
case descriptor.IsList() && isMessage(descriptor):
return redactListField(value)
case descriptor.IsMap() && isMessage(descriptor):
case descriptor.IsMap() && isMessage(descriptor.MapValue()):
// Only when map value are of Message type, we recurse.
return redactMapField(value)
case descriptor.Message() != nil && descriptor.Message().FullName() == anypbFullName:
return redactAny(message, descriptor, value)
Expand Down
40 changes: 40 additions & 0 deletions auth/opa/rpcauth/redact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

proxypb "github.com/Snowflake-Labs/sansshell/proxy"
"github.com/Snowflake-Labs/sansshell/proxy/testdata"
httppb "github.com/Snowflake-Labs/sansshell/services/httpoverrpc"
"github.com/stretchr/testify/assert"
"google.golang.org/protobuf/encoding/protojson"
Expand Down Expand Up @@ -53,6 +54,25 @@ func TestGetRedactedInput(t *testing.T) {
},
}
proxyReqInput, _ := NewRPCAuthInput(context.TODO(), "/Proxy.Proxy/Proxy", proxyReq.ProtoReflect().Interface())

testReq := testdata.TestRequest{
ListScalar: []string{"s1"},
ListMsg: []*testdata.MyNested{
&testdata.MyNested{
Fine: "ok",
Sensitive: "358===",
},
},
MapScalar: map[string]string{"key": "value"},
MapMsg: map[string]*testdata.MyNested{
"key2": &testdata.MyNested{
Fine: "also ok",
Sensitive: "456----",
},
},
}
testdataInput, _ := NewRPCAuthInput(context.TODO(), "/Testdata.TestService/TestUnary",
testReq.ProtoReflect().Interface())
for _, tc := range []struct {
name string
createInputFn func() *RPCAuthInput
Expand Down Expand Up @@ -102,6 +122,26 @@ func TestGetRedactedInput(t *testing.T) {
assert.NoError(t, err)
},
},
{
name: "redacted nested message in map or list fields",
createInputFn: func() *RPCAuthInput {
return testdataInput
},
assertionFn: func(result RPCAuthInput) {
messageType, _ := protoregistry.GlobalTypes.FindMessageByURL(testdataInput.MessageType)
resultMessage := messageType.New().Interface()
err := protojson.Unmarshal([]byte(result.Message), resultMessage)
assert.NoError(t, err)

req := resultMessage.(*testdata.TestRequest)

assert.Equal(t, "--REDACTED--", req.ListMsg[0].Sensitive)
assert.Equal(t, "--REDACTED--", req.MapMsg["key2"].Sensitive)
},
errFunc: func(t *testing.T, err error) {
assert.NoError(t, err)
},
},
{
name: "malformed input should return err",
createInputFn: func() *RPCAuthInput {
Expand Down
Loading

0 comments on commit 261699c

Please sign in to comment.