Skip to content

Commit 9ddee8f

Browse files
authored
Use cryptographically secure password generation (zalando#854)
The current password generation algorithm is extremely deterministic, due to being based on the standard random number generator with a deterministic seed based on the current Unix timestamp (in seconds). This can lead to a number of security issues, including: The same passwords being used in different Kubernetes clusters if the operator is deployed in parallel. (This issue was discovered because of four deployments having the same generated passwords due to automatically being deployed in parallel.) The passwords being easily guessable based on the time the operator pod started when the database was created. (This would typically be present in logs, metrics, etc., that may typically be accessible to more people than should have database access.) Fix this issue by replacing the current randomness source with crypto/rand, which should produce cryptographically secure random data that is virtually unguessable. This will avoid both of the above problems as each deployment will be guaranteed to have unique, indeterministic passwords.
1 parent cf829df commit 9ddee8f

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

pkg/util/util.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package util
22

33
import (
44
"crypto/md5" // #nosec we need it to for PostgreSQL md5 passwords
5+
cryptoRand "crypto/rand"
56
"encoding/hex"
67
"fmt"
8+
"math/big"
79
"math/rand"
810
"regexp"
911
"strings"
@@ -37,13 +39,17 @@ func False() *bool {
3739
return &b
3840
}
3941

40-
// RandomPassword generates random alphanumeric password of a given length.
42+
// RandomPassword generates a secure, random alphanumeric password of a given length.
4143
func RandomPassword(n int) string {
4244
b := make([]byte, n)
4345
for i := range b {
44-
b[i] = passwordChars[rand.Intn(len(passwordChars))]
46+
maxN := big.NewInt(int64(len(passwordChars)))
47+
if n, err := cryptoRand.Int(cryptoRand.Reader, maxN); err != nil {
48+
panic(fmt.Errorf("Unable to generate secure, random password: %v", err))
49+
} else {
50+
b[i] = passwordChars[n.Int64()]
51+
}
4552
}
46-
4753
return string(b)
4854
}
4955

0 commit comments

Comments
 (0)