github.com/cloudfoundry/cli@v7.1.0+incompatible/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 var list []interface{} 43 for _, val := range v { 44 list = append(list, iterateAndRedact(val)) 45 } 46 47 return list 48 case map[string]interface{}: 49 for key, value := range v { 50 if keysToSanitize.MatchString(key) { 51 v[key] = RedactedValue 52 } else { 53 v[key] = iterateAndRedact(value) 54 } 55 } 56 return v 57 } 58 return blob 59 } 60 61 func sanitizeURL(rawURL string) string { 62 sanitized := sanitizeURLPassword.ReplaceAllString(rawURL, fmt.Sprintf("$1://$2:%s@", RedactedValue)) 63 sanitized = sanitizeURIParams.ReplaceAllString(sanitized, fmt.Sprintf("$1=%s", RedactedValue)) 64 return sanitized 65 }