Settings: Fix handling
This commit is contained in:
+1
-15
@@ -1,9 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@@ -19,18 +16,7 @@ func AdminGetSettings(c *models.ReqContext) response.Response {
|
||||
|
||||
for _, key := range section.Keys() {
|
||||
keyName := key.Name()
|
||||
value := key.Value()
|
||||
if strings.Contains(keyName, "secret") || strings.Contains(keyName, "password") || (strings.Contains(keyName, "provider_config")) {
|
||||
value = "************"
|
||||
}
|
||||
if strings.Contains(keyName, "url") {
|
||||
var rgx = regexp.MustCompile(`.*:\/\/([^:]*):([^@]*)@.*?$`)
|
||||
var subs = rgx.FindAllSubmatch([]byte(value), -1)
|
||||
if subs != nil && len(subs[0]) == 3 {
|
||||
value = strings.Replace(value, string(subs[0][1]), "******", 1)
|
||||
value = strings.Replace(value, string(subs[0][2]), "******", 1)
|
||||
}
|
||||
}
|
||||
value := setting.RedactedValue(setting.EnvKey(section.Name(), key.Name()), key.Value())
|
||||
|
||||
jsonSec[keyName] = value
|
||||
}
|
||||
|
||||
+76
-32
@@ -12,6 +12,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -422,38 +423,86 @@ func shouldRedactKey(s string) bool {
|
||||
return strings.Contains(uppercased, "PASSWORD") || strings.Contains(uppercased, "SECRET") || strings.Contains(uppercased, "PROVIDER_CONFIG")
|
||||
}
|
||||
|
||||
func shouldRedactURLKey(s string) bool {
|
||||
uppercased := strings.ToUpper(s)
|
||||
return strings.Contains(uppercased, "DATABASE_URL")
|
||||
func RedactedValue(key, value string) string {
|
||||
uppercased := strings.ToUpper(key)
|
||||
// Sensitive information: password, secrets etc
|
||||
for _, pattern := range []string{
|
||||
"PASSWORD",
|
||||
"SECRET",
|
||||
"PROVIDER_CONFIG",
|
||||
"PRIVATE_KEY",
|
||||
"SECRET_KEY",
|
||||
"CERTIFICATE",
|
||||
"ACCOUNT_KEY",
|
||||
"ENCRYPTION_KEY",
|
||||
"VAULT_TOKEN",
|
||||
"AWSKMS_.*_TOKEN",
|
||||
} {
|
||||
if match, err := regexp.MatchString(pattern, uppercased); match && err == nil {
|
||||
return redactedPassword
|
||||
}
|
||||
}
|
||||
|
||||
for _, exception := range []string{
|
||||
"RUDDERSTACK",
|
||||
"APPLICATION_INSIGHTS",
|
||||
"SENTRY",
|
||||
} {
|
||||
if strings.Contains(uppercased, exception) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
if u, err := RedactedURL(value); err == nil {
|
||||
return u
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func RedactedURL(value string) (string, error) {
|
||||
// Value could be a list of URLs
|
||||
chunks := util.SplitString(value)
|
||||
|
||||
for i, chunk := range chunks {
|
||||
var hasTmpPrefix bool
|
||||
const tmpPrefix = "http://"
|
||||
|
||||
if !strings.Contains(chunk, "://") {
|
||||
chunk = tmpPrefix + chunk
|
||||
hasTmpPrefix = true
|
||||
}
|
||||
|
||||
u, err := url.Parse(chunk)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
redacted := u.Redacted()
|
||||
if hasTmpPrefix {
|
||||
redacted = strings.Replace(redacted, tmpPrefix, "", 1)
|
||||
}
|
||||
|
||||
chunks[i] = redacted
|
||||
}
|
||||
|
||||
if strings.Contains(value, ",") {
|
||||
return strings.Join(chunks, ","), nil
|
||||
}
|
||||
|
||||
return strings.Join(chunks, " "), nil
|
||||
}
|
||||
|
||||
func applyEnvVariableOverrides(file *ini.File) error {
|
||||
appliedEnvOverrides = make([]string, 0)
|
||||
for _, section := range file.Sections() {
|
||||
for _, key := range section.Keys() {
|
||||
envKey := envKey(section.Name(), key.Name())
|
||||
envKey := EnvKey(section.Name(), key.Name())
|
||||
envValue := os.Getenv(envKey)
|
||||
|
||||
if len(envValue) > 0 {
|
||||
key.SetValue(envValue)
|
||||
if shouldRedactKey(envKey) {
|
||||
envValue = redactedPassword
|
||||
}
|
||||
if shouldRedactURLKey(envKey) {
|
||||
u, err := url.Parse(envValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse environment variable. key: %s, value: %s. error: %v", envKey, envValue, err)
|
||||
}
|
||||
ui := u.User
|
||||
if ui != nil {
|
||||
_, exists := ui.Password()
|
||||
if exists {
|
||||
u.User = url.UserPassword(ui.Username(), "-redacted-")
|
||||
envValue = u.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
appliedEnvOverrides = append(appliedEnvOverrides, fmt.Sprintf("%s=%s", envKey, envValue))
|
||||
appliedEnvOverrides = append(appliedEnvOverrides, fmt.Sprintf("%s=%s", envKey, RedactedValue(envKey, envValue)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,7 +568,7 @@ type AnnotationCleanupSettings struct {
|
||||
MaxCount int64
|
||||
}
|
||||
|
||||
func envKey(sectionName string, keyName string) string {
|
||||
func EnvKey(sectionName string, keyName string) string {
|
||||
sN := strings.ToUpper(strings.ReplaceAll(sectionName, ".", "_"))
|
||||
sN = strings.ReplaceAll(sN, "-", "_")
|
||||
kN := strings.ToUpper(strings.ReplaceAll(keyName, ".", "_"))
|
||||
@@ -535,10 +584,8 @@ func applyCommandLineDefaultProperties(props map[string]string, file *ini.File)
|
||||
value, exists := props[keyString]
|
||||
if exists {
|
||||
key.SetValue(value)
|
||||
if shouldRedactKey(keyString) {
|
||||
value = redactedPassword
|
||||
}
|
||||
appliedCommandLineProperties = append(appliedCommandLineProperties, fmt.Sprintf("%s=%s", keyString, value))
|
||||
appliedCommandLineProperties = append(appliedCommandLineProperties,
|
||||
fmt.Sprintf("%s=%s", keyString, RedactedValue(keyString, value)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1037,7 +1084,7 @@ type DynamicSection struct {
|
||||
// Key dynamically overrides keys with environment variables.
|
||||
// As a side effect, the value of the setting key will be updated if an environment variable is present.
|
||||
func (s *DynamicSection) Key(k string) *ini.Key {
|
||||
envKey := envKey(s.section.Name(), k)
|
||||
envKey := EnvKey(s.section.Name(), k)
|
||||
envValue := os.Getenv(envKey)
|
||||
key := s.section.Key(k)
|
||||
|
||||
@@ -1046,10 +1093,7 @@ func (s *DynamicSection) Key(k string) *ini.Key {
|
||||
}
|
||||
|
||||
key.SetValue(envValue)
|
||||
if shouldRedactKey(envKey) {
|
||||
envValue = redactedPassword
|
||||
}
|
||||
s.Logger.Info("Config overridden from Environment variable", "var", fmt.Sprintf("%s=%s", envKey, envValue))
|
||||
s.Logger.Info("Config overridden from Environment variable", "var", fmt.Sprintf("%s=%s", envKey, RedactedValue(envKey, envValue)))
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user