diff --git a/api/main.go b/api/main.go index 220b53a69..5ed4f395f 100644 --- a/api/main.go +++ b/api/main.go @@ -52,7 +52,9 @@ func main() { if err != nil { panic(fmt.Sprintf("Error connecting to socket server at %s %v", *aggregatorAddress, err)) } - go pipeChannelToSocket(socketConnection, harOutputChannel) + filteredHarChannel := make(chan *tap.OutputChannelItem) + go filterHarHeaders(harOutputChannel, filteredHarChannel) + go pipeChannelToSocket(socketConnection, filteredHarChannel) } else if *aggregator { socketHarOutChannel := make(chan *tap.OutputChannelItem, 1000) go api.StartReadingEntries(socketHarOutChannel, nil) @@ -98,6 +100,14 @@ func getTapTargets() []string { return tappedAddressesPerNodeDict[nodeName] } +func filterHarHeaders(inChannel <- chan *tap.OutputChannelItem, outChannel chan *tap.OutputChannelItem) { + for { + message := <- inChannel + utils.FilterSensitiveInfoFromHarRequest(message) + outChannel <- message + } +} + func pipeChannelToSocket(connection *websocket.Conn, messageDataChannel <-chan *tap.OutputChannelItem) { if connection == nil { panic("Websocket connection is nil") diff --git a/api/pkg/utils/consts.go b/api/pkg/utils/consts.go new file mode 100644 index 000000000..377920a51 --- /dev/null +++ b/api/pkg/utils/consts.go @@ -0,0 +1,9 @@ +package utils + +const maskedFieldPlaceholderValue = "[REDACTED]" +var personallyIdentifiableDataFields = []string {"token", "authorization", "authentication", "cookie", "userid", "password", + "username", "user", "key", "passcode", "pass", "auth", "authtoken", "jwt", + "bearer", "clientid", "clientsecret", "redirecturi", "phonenumber", + "zip", "zipcode", "address", "country", "city", "state", "residence", + "name", "firstname", "lastname", "suffix", "middlename", "fname", "lname", + "mname", "date", "birthday", "birthday", "bday", "sender", "receiver"} diff --git a/api/pkg/utils/utils.go b/api/pkg/utils/utils.go index 9ecb89522..8b2638fb1 100644 --- a/api/pkg/utils/utils.go +++ b/api/pkg/utils/utils.go @@ -4,12 +4,15 @@ import ( "encoding/json" "fmt" "github.com/gofiber/fiber/v2" + "github.com/google/martian/har" "log" "mizuserver/pkg/models" + "mizuserver/pkg/tap" "net/url" "os" "os/signal" "reflect" + "strings" "syscall" ) @@ -84,4 +87,86 @@ func GetResolvedBaseEntry(entry models.MizuEntry) models.BaseEntryDetails { func GetBytesFromStruct(v interface{}) []byte{ a, _ := json.Marshal(v) return a -} \ No newline at end of file +} + +func FilterSensitiveInfoFromHarRequest(harOutputItem *tap.OutputChannelItem) { + filterHarHeaders(harOutputItem.HarEntry.Request.Headers) + filterHarHeaders(harOutputItem.HarEntry.Response.Headers) + + harOutputItem.HarEntry.Request.URL = filterUrl(harOutputItem.HarEntry.Request.URL) + + var requestJsonMap map[string] interface{} + err := json.Unmarshal([]byte(harOutputItem.HarEntry.Request.PostData.Text) ,&requestJsonMap) + if err == nil { + filterJsonMap(requestJsonMap) + } + // + //filterJsonMap(harOutputItem.HarEntry.Response.Content.Text) + + + // filter url query params + // filter bodies +} + +func filterHarHeaders(headers []har.Header) { + for _, header := range headers { + if isFieldNameSensitive(header.Name) { + header.Value = maskedFieldPlaceholderValue + } + } +} + +func isFieldNameSensitive(fieldName string) bool { + name := strings.ToLower(fieldName) + name = strings.ReplaceAll(name, "_", "") + name = strings.ReplaceAll(name, "-", "") + name = strings.ReplaceAll(name, " ", "") + + for _, sensitiveField := range personallyIdentifiableDataFields { + if strings.Contains(name, sensitiveField) { + return true + } + } + + return false +} + +func filterJsonMap(jsonMap map[string] interface{}) { + for key, value := range jsonMap { + if value == nil { + return + } + nestedMap, isNested := value.(map[string] interface{}) + if isNested { + filterJsonMap(nestedMap) + } else { + if isFieldNameSensitive(key) { + jsonMap[key] = maskedFieldPlaceholderValue + } + } + } +} + +func filterUrl(originalUrl string) string { + parsedUrl, err := url.Parse(originalUrl) + if err != nil { + return originalUrl + } else { + if len(parsedUrl.RawQuery) > 0 { + newQueryArgs := make([]string, 0) + for urlQueryParamName, urlQueryParamValues := range parsedUrl.Query() { + newValues := urlQueryParamValues + if isFieldNameSensitive(urlQueryParamName) { + newValues = []string {maskedFieldPlaceholderValue} + } + for value := range newValues { + newQueryArgs = append(newQueryArgs, fmt.Sprintf("%s=%s", urlQueryParamName, value)) + } + } + + parsedUrl.RawQuery = strings.Join(newQueryArgs, "&") + } + + return parsedUrl.String() + } +}