Skip to content

fix: Redact password field in RemoteInfo type #1322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions pkg/pb/synthetic_monitoring/checks_extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package synthetic_monitoring
//go:generate ../../../scripts/enumer -type=MultiHttpEntryAssertionType,MultiHttpEntryAssertionSubjectVariant,MultiHttpEntryAssertionConditionVariant,MultiHttpEntryVariableType -trimprefix=MultiHttpEntryAssertionType_,MultiHttpEntryAssertionSubjectVariant_,MultiHttpEntryAssertionConditionVariant_,MultiHttpEntryVariableType_ -transform=upper -output=multihttp_string.go

import (
"encoding/json"
"errors"
"fmt"
"mime"
Expand All @@ -30,6 +31,7 @@ import (
"strings"
"time"

"github.com/rs/zerolog"
"golang.org/x/exp/constraints"
"golang.org/x/net/http/httpguts"
)
Expand Down Expand Up @@ -1585,3 +1587,19 @@ func GetCheckInstance(checkType CheckType) Check {

return instance
}

func (ri RemoteInfo) MarshalZerologObject(e *zerolog.Event) {
e.Str("name", ri.Name).
Str("url", ri.Url).
Str("username", ri.Username).
Str("password", "<encrypted>")
}

func (ri RemoteInfo) MarshalJSON() ([]byte, error) {
type T RemoteInfo
var tmp T = T(ri)

tmp.Password = `<encrypted>`

return json.Marshal(tmp)
}
72 changes: 72 additions & 0 deletions pkg/pb/synthetic_monitoring/checks_extra_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package synthetic_monitoring

import (
"bytes"
"encoding/json"
"errors"
"flag"
"reflect"
"strings"
"testing"

"github.com/rs/zerolog"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -1973,3 +1976,72 @@ func TestGetCheckInstance(t *testing.T) {
require.NoError(t, check.Validate())
}
}

func requireRemoteInfoFields(t *testing.T) {
t.Helper()

// The expected fields in the RemoteInfo struct. It's necessary to
// assert this list so that if the implementation ever changes, we can
// go update the MarshalZerologObject method accordingly.
expectedFields := []string{
"Name",
"Url",
"Username",
"Password",
}

remoteInfoType := reflect.TypeOf(RemoteInfo{})
actualFields := make([]string, 0, remoteInfoType.NumField())

for i := range remoteInfoType.NumField() {
field := remoteInfoType.Field(i)
if field.IsExported() {
actualFields = append(actualFields, field.Name)
}
}

require.ElementsMatch(t, expectedFields, actualFields,
"RemoteInfo struct fields have changed. Update the expected fields list and review any code that depends on the field order.")
}

func TestRemoteInfoMarshalZerologObject(t *testing.T) {
requireRemoteInfoFields(t)

remoteInfo := RemoteInfo{
Name: "the name",
Url: "https://example.com",
Username: "the username",
Password: "the password",
}

var buf bytes.Buffer
logger := zerolog.New(&buf)

logger.Info().Interface("remote_info", remoteInfo).Send()

// Note that the order of the expected fields is fixed. If the
// implementation changes, this test will break.
expected := `{"level":"info","remote_info":{"name":"the name","url":"https://example.com","username":"the username","password":"<encrypted>"}}` + "\n"
actual := buf.String()

require.Equal(t, expected, actual)
}

func TestRemoteInfoMarshalJSON(t *testing.T) {
requireRemoteInfoFields(t)

remoteInfo := RemoteInfo{
Name: "the name",
Url: "https://example.com",
Username: "the username",
Password: "the password",
}

var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(&remoteInfo)
require.NoError(t, err)

expected := `{"name":"the name","url":"https://example.com","username":"the username","password":"\u003cencrypted\u003e"}`
actual := strings.TrimSpace(buf.String())
require.Equal(t, expected, actual, "JSON encoding of RemoteInfo did not match expected output")
}
Loading