fix: add log sanitization for Secret kind in updateResource

- Added a new function `desensitizeLog` to sanitize logs by replacing sensitive data in a Secret with "***".
- Modified the `updateResource` function to use `desensitizeLog` when the kind is "Secret".
- Added a test case for the `desensitizeLog` function to ensure it works as expected.

Signed-off-by: Daniel Hu <tao.hu@merico.dev>
pull/12183/head
Daniel Hu 1 year ago
parent 03911aeab7
commit 309cad9d9f

@ -687,7 +687,11 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
c.Log("Patch %s %q in namespace %s", kind, target.Name, target.Namespace)
obj, err = helper.Patch(target.Namespace, target.Name, patchType, patch, nil)
if err != nil {
return errors.Wrapf(err, "cannot patch %q with kind %s", target.Name, kind)
sanitizeLog := err.Error()
if kind == "Secret" {
sanitizeLog = desensitizeLog(err.Error())
}
return errors.Wrapf(errors.New(sanitizeLog), "cannot patch %q with kind %s", target.Name, kind)
}
}
@ -695,6 +699,46 @@ func updateResource(c *Client, target *resource.Info, currentObj runtime.Object,
return nil
}
// desensitizeLog replaces the data in a Secret with {"key": "***"}.
// e.g. "data": {"username": "admin", "password": "password"} becomes "data": {"username": "***", "password": "***"}
func desensitizeLog(log string) string {
start := strings.Index(log, `{\"apiVersion`)
end := strings.Index(log, `,\"kind\":\"Secret\"`)
if start == -1 || end == -1 {
return log
}
// Extract the JSON string and add a } at the end
jsonStr := log[start:end] + "}"
jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"")
// Parse the JSON string into a map
var data map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &data)
if err != nil {
return log
}
// Desensitize the values in the data map
if dataMap, ok := data["data"].(map[string]interface{}); ok {
for k := range dataMap {
dataMap[k] = "***"
}
}
// Convert the map back to JSON string
newJsonStr, err := json.Marshal(data)
if err != nil {
return log
}
// Replace the original JSON string with the new one in the log
newJsonStr = []byte(strings.ReplaceAll(string(newJsonStr), "\"", "\\\""))
newLog := log[:start] + string(newJsonStr[:len(newJsonStr)-1]) + log[end:]
return newLog
}
func (c *Client) watchUntilReady(timeout time.Duration, info *resource.Info) error {
kind := info.Mapping.GroupVersionKind.Kind
switch kind {

@ -558,3 +558,19 @@ spec:
ports:
- containerPort: 80
`
func TestDesensitizeLog(t *testing.T) {
log := `Error: UPGRADE FAILED: cannot patch "mysecret" with kind Secret: "" is invalid: patch: Invalid value: "{\"apiVersion\":\"v1\",\"data\":{\"mykey1\":\"hello\", \"mykey2\":\"world\"},\"kind\":\"Secret\",\"metadata\"……,\"type\":\"Opaque\"}": illegal base64 data at input byte 12`
expected1 := `\"mykey1\":\"***\"`
expected2 := `\"mykey2\":\"***\"`
result := desensitizeLog(log)
if !strings.Contains(result, expected1) {
t.Errorf("Expected %s to contain %s", result, expected1)
}
if !strings.Contains(result, expected2) {
t.Errorf("Expected %s to contain %s", result, expected2)
}
}

Loading…
Cancel
Save