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-project.js
*_test.go
cover.*

View file

@ -15,6 +15,8 @@ package common
import (
"fmt"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
"io/ioutil"
"os"
"path/filepath"
@ -22,6 +24,10 @@ import (
var (
configPath string = filepath.Join(GetCurrentDir(), CONFIG_PATH+"config.json")
configKeysToEncrypt []string = []string{
"middleware.identity_provider.params",
"middleware.attribute_mapping.params",
}
)
func LoadConfig() ([]byte, error) {
@ -34,14 +40,28 @@ func LoadConfig() ([]byte, error) {
if err != nil {
return nil, err
}
if s := os.Getenv("CONFIG_SECRET"); s != "" {
t, err := DecryptString(Hash(s, 16), string(cFile))
configStr := 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 {
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 {
@ -53,17 +73,29 @@ func SaveConfig(v []byte) error {
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()
}

View file

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