From e381b81b4700b4f420a77724ab3c457877791f8e Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 28 Jan 2026 13:25:19 -0800 Subject: [PATCH] s3tables: use crypto/rand for secure version token generation Replaced math/rand with crypto/rand to ensure version tokens are cryptographically secure and unpredictable for optimistic concurrency control. --- weed/s3api/s3tables/utils.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/weed/s3api/s3tables/utils.go b/weed/s3api/s3tables/utils.go index f744ccff1..994446330 100644 --- a/weed/s3api/s3tables/utils.go +++ b/weed/s3api/s3tables/utils.go @@ -1,8 +1,9 @@ package s3tables import ( + "crypto/rand" + "encoding/hex" "fmt" - "math/rand" "net/url" "path" "regexp" @@ -12,7 +13,7 @@ import ( var ( bucketARNPattern = regexp.MustCompile(`^arn:aws:s3tables:[^:]*:[^:]*:bucket/([a-z0-9_-]+)$`) - tableARNPattern = regexp.MustCompile(`^arn:aws:s3tables:[^:]*:[^:]*:bucket/([a-z0-9_-]+)/table/([^/]+)/([a-z0-9_]+)$`) + tableARNPattern = regexp.MustCompile(`^arn:aws:s3tables:[^:]*:[^:]*:bucket/([a-z0-9_-]+)/table/([a-z0-9_]+)/([a-z0-9_]+)$`) bucketNamePattern = regexp.MustCompile(`^[a-z0-9_-]+$`) ) @@ -105,9 +106,14 @@ func isValidBucketName(name string) bool { return bucketNamePattern.MatchString(name) } -// generateVersionToken generates a unique version token +// generateVersionToken generates a unique, unpredictable version token func generateVersionToken() string { - return fmt.Sprintf("%d_%d", time.Now().UnixNano(), rand.Int63()) + b := make([]byte, 16) + if _, err := rand.Read(b); err != nil { + // Fallback to timestamp if crypto/rand fails + return fmt.Sprintf("%x", time.Now().UnixNano()) + } + return hex.EncodeToString(b) } // splitPath splits a path into directory and name components using stdlib