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  }