fix: don't log token metadata field in grpc request log

This field might contain sensitive information, so better to hide it in
the logs.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
This commit is contained in:
Andrey Smirnov 2019-12-26 18:54:56 +00:00 committed by Andrew Rynhard
parent c8d3da5376
commit f1a7f86703
2 changed files with 51 additions and 10 deletions

View File

@ -29,7 +29,12 @@ func NewMiddleware(logger *log.Logger) *Middleware {
}
}
func extractMetadata(ctx context.Context) string {
var sensitiveFields = map[string]struct{}{
"token": {},
}
// ExtractMetadata formats metadata from incoming grpc context as string for the log.
func ExtractMetadata(ctx context.Context) string {
md, _ := metadata.FromIncomingContext(ctx)
keys := make([]string, 0, len(md))
@ -42,7 +47,13 @@ func extractMetadata(ctx context.Context) string {
pairs := make([]string, 0, len(keys))
for _, key := range keys {
pairs = append(pairs, key+"="+strings.Join(md[key], ","))
value := strings.Join(md[key], ",")
if _, sensitive := sensitiveFields[key]; sensitive {
value = "<hidden>"
}
pairs = append(pairs, key+"="+value)
}
return strings.Join(pairs, ";")
@ -63,7 +74,7 @@ func (m *Middleware) UnaryInterceptor() grpc.UnaryServerInterceptor {
msg = err.Error()
}
m.logger.Printf("%s [%s] %s unary %s (%s)", code, info.FullMethod, duration, msg, extractMetadata(ctx))
m.logger.Printf("%s [%s] %s unary %s (%s)", code, info.FullMethod, duration, msg, ExtractMetadata(ctx))
return resp, err
}
@ -84,7 +95,7 @@ func (m *Middleware) StreamInterceptor() grpc.StreamServerInterceptor {
msg = err.Error()
}
m.logger.Printf("%s [%s] %s stream %s (%s)", code, info.FullMethod, duration, msg, extractMetadata(stream.Context()))
m.logger.Printf("%s [%s] %s stream %s (%s)", code, info.FullMethod, duration, msg, ExtractMetadata(stream.Context()))
return err
}

View File

@ -4,11 +4,41 @@
package log_test
import "testing"
import (
"context"
"testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
"github.com/stretchr/testify/assert"
metadata "google.golang.org/grpc/metadata"
"github.com/talos-systems/talos/pkg/grpc/middleware/log"
)
func TestExtractMetadata(t *testing.T) {
for _, test := range []struct {
name string
md metadata.MD
expected string
}{
{
name: "empty",
md: metadata.MD{},
expected: "",
},
{
name: "regular",
md: metadata.Pairs("foo", "bar", "one", "two", "a", "b"),
expected: "a=b;foo=bar;one=two",
},
{
name: "sensitive",
md: metadata.Pairs("foo", "bar", "token", "secret"),
expected: "foo=bar;token=<hidden>",
},
} {
ctx := context.Background()
ctx = metadata.NewIncomingContext(ctx, test.md)
assert.Equal(t, test.expected, log.ExtractMetadata(ctx), test.name)
}
}