github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/util/ui/sanitize_json.go (about) 1 package ui 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "regexp" 8 ) 9 10 var keysToSanitize = regexp.MustCompile("(?i)token|password") 11 var sanitizeURIParams = regexp.MustCompile(`([&?]password)=[A-Za-z0-9\-._~!$'()*+,;=:@/?]*`) 12 var sanitizeURLPassword = regexp.MustCompile(`([\d\w]+):\/\/([^:]+):(?:[^@]+)@`) 13 14 func SanitizeJSON(raw []byte) ([]byte, error) { 15 var result interface{} 16 decoder := json.NewDecoder(bytes.NewBuffer(raw)) 17 decoder.UseNumber() 18 err := decoder.Decode(&result) 19 if err != nil { 20 return nil, err 21 } 22 23 sanitized := iterateAndRedact(result) 24 25 buff := new(bytes.Buffer) 26 encoder := json.NewEncoder(buff) 27 encoder.SetEscapeHTML(false) 28 encoder.SetIndent("", " ") 29 err = encoder.Encode(sanitized) 30 if err != nil { 31 return nil, err 32 } 33 34 return buff.Bytes(), nil 35 } 36 37 func iterateAndRedact(blob interface{}) interface{} { 38 switch v := blob.(type) { 39 case string: 40 return sanitizeURL(v) 41 case []interface{}: 42 list := make([]interface{}, len(v)) 43 44 for index, val := range v { 45 list[index] = iterateAndRedact(val) 46 } 47 48 return list 49 case map[string]interface{}: 50 for key, value := range v { 51 if keysToSanitize.MatchString(key) { 52 v[key] = RedactedValue 53 } else { 54 v[key] = iterateAndRedact(value) 55 } 56 } 57 return v 58 } 59 return blob 60 } 61 62 func sanitizeURL(rawURL string) string { 63 sanitized := sanitizeURLPassword.ReplaceAllString(rawURL, fmt.Sprintf("$1://$2:%s@", RedactedValue)) 64 sanitized = sanitizeURIParams.ReplaceAllString(sanitized, fmt.Sprintf("$1=%s", RedactedValue)) 65 return sanitized 66 }