CVE-2022-0664: Use of Hard-coded Cryptographic Key (CWE-321)
value: Use of Hard-coded Cryptographic Key in Go github.com/gravitl/netmaker prior to 0.8.5,0.9.4,0.10.0,0.10.1.
CWE description: The use of a hard-coded cryptographic key significantly increases the possibility that encrypted data may be recovered.
CVSS v3 base score: 9.8
Published: 2022-02-18T14:15Z
Repository: https://github.com/gravitl/netmaker
Language: Go
Files changed: logic/jwts.go, logic/util.go
Commit date: 2022-02-15 21:50:47 -0500
Commit message: hotfix 2

Diff: diff --git a/logic/jwts.go b/logic/jwts.go
index 54bfbb7..7cbd116 100644
--- a/logic/jwts.go
+++ b/logic/jwts.go
@@ -15,11 +15,15 @@ var jwtSecretKey []byte
 
 // SetJWTSecret - sets the jwt secret on server startup
 func SetJWTSecret() {
 	currentSecret, jwtErr := FetchJWTSecret()
 	if jwtErr != nil {
-		jwtSecretKey = []byte(RandomString(64)) // 512 bit random password
+		newValue, err := GenerateCryptoString(64)
+		if err != nil {
+			logger.FatalLog("something went wrong when generating JWT signature")
+		}
+		jwtSecretKey = []byte(newValue) // 512 bit random password
 		if err := StoreJWTSecret(string(jwtSecretKey)); err != nil {
 			logger.FatalLog("something went wrong when configuring JWT authentication")
 		}
 	} else {
 		jwtSecretKey = []byte(currentSecret)
diff --git a/logic/util.go b/logic/util.go
index 2177a4a..ed4766e 100644
--- a/logic/util.go
+++ b/logic/util.go
@@ -1,12 +1,14 @@
 // package for logicing client and server code
 package logic
 
 import (
+	crand "crypto/rand"
 	"encoding/base64"
 	"encoding/json"
 	"fmt"
+	"math/big"
 	"math/rand"
 	"net"
 	"os"
 	"strconv"
 	"strings"
@@ -83,33 +85,24 @@ func SetNetworkNodesLastModified(networkName string) error {
 		return err
 	}
 	return nil
 }
 
-// // GetNode - fetches a node from database
-// func GetNode(macaddress string, network string) (models.Node, error) {
-// 	var node models.Node
-
-// 	key, err := GetRecordKey(macaddress, network)
-// 	if err != nil {
-// 		return node, err
-// 	}
-// 	data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
-// 	if err != nil {
-// 		if data == "" {
-// 			data, _ = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
-// 			err = json.Unmarshal([]byte(data), &node)
-// 		}
-// 		return node, err
-// 	}
-// 	if err = json.Unmarshal([]byte(data), &node); err != nil {
-// 		return node, err
-// 	}
-// 	SetNodeDefaults(&node)
+// GenerateCryptoString - generates random string of n length
+func GenerateCryptoString(n int) (string, error) {
+	const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
+	ret := make([]byte, n)
+	for i := range ret {
+		num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars))))
+		if err != nil {
+			return "", err
+		}
+		ret[i] = chars[num.Int64()]
+	}
 
-// 	return node, err
-// }
+	return string(ret), nil
+}
 
 // DeleteNodeByID - deletes a node from database or moves into delete nodes table
 func DeleteNodeByID(node *models.Node, exterminate bool) error {
 	var err error
 	var key = node.ID

Vulnerable code: 		jwtSecretKey = []byte(RandomString(64)) // 512 bit random password
// // GetNode - fetches a node from database
// func GetNode(macaddress string, network string) (models.Node, error) {
// 	var node models.Node

// 	key, err := GetRecordKey(macaddress, network)
// 	if err != nil {
// 		return node, err
// 	}
// 	data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
// 	if err != nil {
// 		if data == "" {
// 			data, _ = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
// 			err = json.Unmarshal([]byte(data), &node)
// 		}
// 		return node, err
// 	}
// 	if err = json.Unmarshal([]byte(data), &node); err != nil {
// 		return node, err
// 	}
// 	SetNodeDefaults(&node)
// 	return node, err
// }
Fixed code: 		newValue, err := GenerateCryptoString(64)
		if err != nil {
			logger.FatalLog("something went wrong when generating JWT signature")
		}
		jwtSecretKey = []byte(newValue) // 512 bit random password
	crand "crypto/rand"
	"math/big"
// GenerateCryptoString - generates random string of n length
func GenerateCryptoString(n int) (string, error) {
	const chars = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"
	ret := make([]byte, n)
	for i := range ret {
		num, err := crand.Int(crand.Reader, big.NewInt(int64(len(chars))))
		if err != nil {
			return "", err
		}
		ret[i] = chars[num.Int64()]
	}
	return string(ret), nil
}