Critical security vulnerabilities exist in both the UUIDv4() and UUID() functions of the github.com/gofiber/utils package. When the system's cryptographic random number generator (crypto/rand) fails, both functions silently fall back to returning predictable UUID values, including the zero UUID "00000000-0000-0000-0000-000000000000". This compromises the security of all Fiber applications using these functions for security-critical operations.
Both functions are vulnerable to the same root cause (crypto/rand failure):
- UUIDv4(): Indirect vulnerability through uuid.NewRandom() → crypto/rand.Read() → fallback to UUID()
- UUID(): Direct vulnerability through crypto/rand.Read(uuidSeed[:]) → silent zero UUID return
github.com/gofiber/utilsUUIDv4() and UUID()string (both functions)common.go:93-99 (UUIDv4), common.go:60-89 (UUID)The vulnerability occurs through two related but distinct failure paths, both ultimately caused by crypto/rand.Read() failures:
UUIDv4() calls google/uuid.NewRandom() which internally uses crypto/rand.Read()uuid.NewRandom() fails due to entropy exhaustion, UUIDv4() falls back to the internal UUID() functionUUID() directly calls crypto/rand.Read(uuidSeed[:]) to seed its internal stateUUID() silently fails and returns the zero UUID "00000000-0000-0000-0000-000000000000"Both functions are vulnerable to the same root cause (crypto/rand failure):
- UUIDv4(): Indirect vulnerability through uuid.NewRandom() → crypto/rand.Read() → fallback to UUID()
- UUID(): Direct vulnerability through crypto/rand.Read(uuidSeed[:]) → silent zero UUID return
// Vulnerable code in UUIDv4() - Indirect rand.Read() failure
func UUIDv4() string {
token, err := uuid.NewRandom() // Uses crypto/rand.Read() internally
if err != nil {
return UUID() // Dangerous fallback - no error returned to application
}
return token.String()
}
// Vulnerable fallback function UUID() - Direct rand.Read() failure
func UUID() string {
uuidSetup.Do(func() {
if _, err := rand.Read(uuidSeed[:]); err != nil { // Direct crypto/rand.Read() call
return // Silent failure - no seeding, uuidCounter remains 0
}
uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])
})
if atomic.LoadUint64(&uuidCounter) <= 0 {
return "00000000-0000-0000-0000-000000000000" // Zero UUID returned silently
}
// ... generate UUID from counter
}
Root Cause: Both vulnerabilities stem from crypto/rand.Read() failures, but occur through different code paths with the same dangerous silent failure behavior.
This issue is especially severe because many Fiber middleware packages (session, CSRF, auth, rate-limit, request-ID, etc.) default to utils.UUIDv4() for generating security-sensitive identifiers. A failure in crypto/rand would cause every generated identifier across the entire application to collapse to a single predictable value (often the zero UUID), resulting in:
Importantly, while true entropy exhaustion is extremely rare on modern Linux systems, entropy access failures (e.g., restricted /dev/random//dev/urandom access, broken container environments, sandbox restrictions, misconfigured VMs, or FIPS-mode RNG failures) are more realistic failure modes. In these scenarios, crypto/rand may return errors immediately — triggering the vulnerable fallback paths.
The vulnerability can be demonstrated by examining the fallback behavior in the source code. When crypto/rand fails:
uuid.NewRandom() fails (indirect crypto/rand.Read() failure)UUIDv4() calls UUID() as fallback with no error returnedUUID() seeding fails directly via crypto/rand.Read(uuidSeed[:])"00000000-0000-0000-0000-000000000000" is returned silentlyBoth UUIDv4() and UUID() exhibit the same dangerous silent failure behavior when crypto/rand is unavailable.
github.com/gofiber/utils containing the UUIDv4() functionUUIDv4() for securityReplace usage of utils.UUIDv4() with uuid.New() or wait for fix:
// Instead of:
sessionID := utils.UUIDv4()
// Use:
sessionID := uuid.New()
Modify utils.UUIDv4() and utils.UUID()to fail explicitly when cryptographic randomness is unavailable:
func UUIDv4() string {
token, err := uuid.NewRandom()
if err != nil {
panic(fmt.Sprintf("utils: failed to generate secure UUID: %v", err))
}
return token.String()
}
func UUID() string {
uuidSetup.Do(func() {
if _, err := rand.Read(uuidSeed[:]); err != nil {
panic(fmt.Sprintf("utils: failed to seed UUID generator: %v", err))
}
uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])
})
if atomic.LoadUint64(&uuidCounter) <= 0 {
panic("utils: UUID generator not properly seeded")
}
// ... generate UUID from counter
}
Applications can detect if they're affected by:
1. Checking if they use github.com/gofiber/utils package
2. Searching for UUIDv4() usage in security-critical code paths
3. Reviewing middleware configurations that use UUIDv4 as defaults
or
UUIDv4() for security identifiers.Reported by: @sixcolors
{
"github_reviewed": true,
"nvd_published_at": null,
"severity": "CRITICAL",
"cwe_ids": [
"CWE-252",
"CWE-331",
"CWE-338"
],
"github_reviewed_at": "2025-12-08T17:57:26Z"
}