feature (config): encrypt sensitive fields in config.json

This commit is contained in:
Mickael Kerjean 2022-11-22 08:12:36 +11:00
parent 6eb26e9a70
commit cb7f1693bd
3 changed files with 55 additions and 24 deletions

1
.gitignore vendored
View file

@ -17,3 +17,4 @@ package-lock.json
.tern-port .tern-port
.tern-project.js .tern-project.js
*_test.go *_test.go
cover.*

View file

@ -15,6 +15,8 @@ package common
import ( import (
"fmt" "fmt"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -22,6 +24,10 @@ import (
var ( var (
configPath string = filepath.Join(GetCurrentDir(), CONFIG_PATH+"config.json") configPath string = filepath.Join(GetCurrentDir(), CONFIG_PATH+"config.json")
configKeysToEncrypt []string = []string{
"middleware.identity_provider.params",
"middleware.attribute_mapping.params",
}
) )
func LoadConfig() ([]byte, error) { func LoadConfig() ([]byte, error) {
@ -34,14 +40,28 @@ func LoadConfig() ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if s := os.Getenv("CONFIG_SECRET"); s != "" { configStr := string(cFile)
t, err := DecryptString(Hash(s, 16), string(cFile)) for _, jsonPathWithEncryptedData := range configKeysToEncrypt {
p := gjson.Get(configStr, jsonPathWithEncryptedData).String()
if p == "" {
continue
}
key := os.Getenv("CONFIG_SECRET")
if key == "" {
InitSecretDerivate(gjson.Get(configStr, "general.secret_key").String())
key = SECRET_KEY_DERIVATE_FOR_PROOF
}
t, err := DecryptString(Hash(key, 16), p)
if err != nil { if err != nil {
return cFile, nil continue
} }
return []byte(t), err val, err := sjson.Set(configStr, jsonPathWithEncryptedData, t)
if err != nil {
continue
} }
return cFile, nil configStr = val
}
return []byte(configStr), nil
} }
func SaveConfig(v []byte) error { func SaveConfig(v []byte) error {
@ -53,17 +73,29 @@ func SaveConfig(v []byte) error {
configPath, configPath,
) )
} }
cFile := PrettyPrint([]byte(v))
if s := os.Getenv("CONFIG_SECRET"); s != "" {
t, err := EncryptString(Hash(s, 16), string(cFile))
if err != nil {
Log.Error("common::config_state SaveConfig '%s'", err.Error())
file.Close()
return err
}
cFile = []byte(t)
}
file.Write(cFile) configStr := string(v)
for _, jsonPath := range configKeysToEncrypt {
key := os.Getenv("CONFIG_SECRET")
if key == "" {
key = SECRET_KEY_DERIVATE_FOR_PROOF
}
p := gjson.Get(configStr, jsonPath).String()
if p == "" {
continue
}
t, err := EncryptString(Hash(key, 16), p)
if err != nil {
Log.Warning("common::config_state cannot encrypt config path '%s'", jsonPath)
continue
}
val, err := sjson.Set(configStr, jsonPath, t)
if err != nil {
Log.Warning("common::config_state cannot put json value in config '%s'", jsonPath)
continue
}
configStr = val
}
file.Write(PrettyPrint([]byte(configStr)))
return file.Close() return file.Close()
} }

View file

@ -12,7 +12,6 @@ import (
"github.com/tredoe/osutil/user/crypt/sha256_crypt" "github.com/tredoe/osutil/user/crypt/sha256_crypt"
"github.com/tredoe/osutil/user/crypt/sha512_crypt" "github.com/tredoe/osutil/user/crypt/sha512_crypt"
"net/http" "net/http"
"os"
"strings" "strings"
) )
@ -97,6 +96,7 @@ func (this Htpasswd) Callback(formData map[string]string, idpParams map[string]s
} else if verifyPassword( } else if verifyPassword(
formData["password"], formData["password"],
strings.SplitN(pair[1], ":", 2)[0], // filter out unwanted fields from hash strings.SplitN(pair[1], ":", 2)[0], // filter out unwanted fields from hash
formData["user"],
) == false { ) == false {
continue continue
} }
@ -114,11 +114,9 @@ func (this Htpasswd) Callback(formData map[string]string, idpParams map[string]s
return nil, ErrAuthenticationFailed return nil, ErrAuthenticationFailed
} }
func verifyPassword(password string, hash string) bool { func verifyPassword(password string, hash string, _user string) bool {
if password == hash { if password == hash {
if s := os.Getenv("CONFIG_SECRET"); s == "" { Log.Warning("plg_authenticate_htpasswd password for user '%s' isn't stored in a secure way, you should hash your password using something like 'openssl passwd -6'", _user)
Log.Warning("plg_authenticate_htpasswd your password shouldn't be stored in clear text!")
}
return true return true
} else if strings.HasPrefix(hash, "{SHA}") { } else if strings.HasPrefix(hash, "{SHA}") {
d := sha1.New() d := sha1.New()