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  }