CVE-2023-46740 (published 2024-01-03T17:15Z)

CubeFS is an open-source cloud-native file storage system. Prior to version 3.3.1, CubeFS used an insecure random string generator to generate user-specific, sensitive keys used to authenticate users in a CubeFS deployment. This could allow an attacker to predict and/or guess the generated string and impersonate a user thereby obtaining higher privileges. When CubeFS creates new users, it creates a piece of sensitive information for the user called the “accessKey”. To create the "accesKey", CubeFS uses an insecure string generator which makes it easy to guess and thereby impersonate the created user. An attacker could leverage the predictable random string generator and guess a users access key and impersonate the user to obtain higher privileges. The issue has been fixed in v3.3.1. There is no other mitigation than to upgrade.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-330
cwe_name: Use of Insufficiently Random Values
description: The product uses insufficiently random numbers or values in a security context that depends on unpredictable numbers.
extended_description: When product generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.
         

Fix information:
repo_url: https://github.com/cubefs/cubefs
commit_details: repo_url: https://github.com/cubefs/cubefs
author: true1064
author_date: 2023-10-23 10:00:13+08:00
msg: [Enhancement]: Optimize insecure random number generation in function util/string.go:RandomString
close: #2696
Signed-off-by: true1064 <tangjingyu@oppo.com>
repository: repo_url: https://github.com/cubefs/cubefs
repo_name: cubefs/cubefs
description: cloud-native distributed storage
repo_language: Go
owner: cubefs
file_changes: filename: packet.go
change_type: ModificationType.MODIFY
diff: @@ -596,6 +596,8 @@ func (p *Packet) GetOpMsg() (m string) {
 		m = "OpLcNodeScan"
 	case OpLcNodeSnapshotVerDel:
 		m = "OpLcNodeSnapshotVerDel"
+	case OpMetaReadDirOnly:
+		m = "OpMetaReadDirOnly"
 	default:
 		m = fmt.Sprintf("op:%v not found", p.Opcode)
 	}

programming_language: Go
filename: stream_writer.go
change_type: ModificationType.MODIFY
diff: @@ -395,7 +395,8 @@ begin:
 				}
 			}
 			// try append write, get response
-			log.LogDebugf("action[streamer.write] doAppendWrite req %v FileOffset %v size %v", req.ExtentKey, req.FileOffset, req.Size)
+			log.LogDebugf("action[streamer.write] doAppendWrite req: ExtentKey(%v) FileOffset(%v) size(%v)",
+				req.ExtentKey, req.FileOffset, req.Size)
 			var status int32
 			// First, attempt sequential writes using neighboring extent keys. If the last extent has a different version,
 			// it indicates that the extent may have been fully utilized by the previous version.

programming_language: Go
filename: string.go
change_type: ModificationType.MODIFY
diff: @@ -15,9 +15,9 @@
 package util
 
 import (
-	"math/rand"
+	"crypto/rand"
+	"math/big"
 	"strings"
-	"time"
 )
 
 func SubString(sourceString string, begin, end int) string {
@@ -59,9 +59,9 @@ func RandomString(length int, seed RandomSeed) string {
 	runs := seed.Runes()
 	result := ""
 	for i := 0; i < length; i++ {
-		rand.Seed(time.Now().UnixNano())
-		randNumber := rand.Intn(len(runs))
-		result += string(runs[randNumber])
+		lenInt64 := int64(len(runs))
+		randNumber, _ := rand.Int(rand.Reader, big.NewInt(lenInt64))
+		result += string(runs[randNumber.Uint64()])
 	}
 	return result
 }

programming_language: Go