Home > Enterprise >  Conditionally print debug info containing sensitive data
Conditionally print debug info containing sensitive data

Time:09-17

I am running a Go program as a k8s job.

The application sends an API request to an elasticsearch cluster to create users, therefore it will contain sensitive data (user's password).

    requestDump, err := httputil.DumpRequest(req, true)
    responseDump, err := httputil.DumpResponse(resp, true)
    esapiClient.log.Printf("got response code %d when creating user: %s\n", resp.StatusCode, user.Username)
    if resp.StatusCode != http.StatusOK {
        esapiClient.log.Printf("error: got response code: %d when creating user %s\n", resp.StatusCode, user.Username)
        esapiClient.log.Println("Request\n", string(requestDump))
        esapiClient.log.Println("Response\n", string(responseDump))
        return ErrResponseCode
    }

When things go south, I want to be able to dump the request and the responses (especially in 400 cases) to check what went wrong (mainly with potentially malformed requests).

What is the recommended way of of doing this? Are log levels the only way around this?

CodePudding user response:

Log levels is a non-solution. Your goal should be not having PII (personally identifiable information) end up in your log dumps altogether, including when you start the service in debug mode.

Depending on how you do the logging, just implement the relevant interfaces on your structs and omit or redact fields that contain PII. In case of fields where you need to have some clue about the original value for debugging purposes, you can redact only a part of it.

For example, if you log with fmt verbs or similar, you can implement the Stringer interface:

type User struct {
    Name     string
    Password string
}

func (u User) String() string {
    return fmt.Sprintf("{%s %s}", u.Name, "*****")
}


func main() {
    u := User{"pkaramol", "secret"}
    fmt.Println(u) // {pkaramol *****}
    
}

If you log in JSON, implement MarshalJSON to redact, or use the struct tag json:"-" to omit:

func (u User) MarshalJSON() ([]byte, error) {
    return json.Marshal(map[string]interface{}{
        "name": u.Name,
        "password": "*****",
    })
}

func main() {
    u := User{"pkaramol", "secret"}
    b, _ := json.Marshal()
    fmt.Println(string(b)) // {"name":"pkaramol","password":"*****"}
}
  • Related