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.
This commit is contained in:
Chris Lu
2026-01-28 13:25:19 -08:00
parent 89b85bfd5e
commit e381b81b47

View File

@@ -1,8 +1,9 @@
package s3tables package s3tables
import ( import (
"crypto/rand"
"encoding/hex"
"fmt" "fmt"
"math/rand"
"net/url" "net/url"
"path" "path"
"regexp" "regexp"
@@ -12,7 +13,7 @@ import (
var ( var (
bucketARNPattern = regexp.MustCompile(`^arn:aws:s3tables:[^:]*:[^:]*:bucket/([a-z0-9_-]+)$`) 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_-]+$`) bucketNamePattern = regexp.MustCompile(`^[a-z0-9_-]+$`)
) )
@@ -105,9 +106,14 @@ func isValidBucketName(name string) bool {
return bucketNamePattern.MatchString(name) return bucketNamePattern.MatchString(name)
} }
// generateVersionToken generates a unique version token // generateVersionToken generates a unique, unpredictable version token
func generateVersionToken() string { 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 // splitPath splits a path into directory and name components using stdlib