logo

Database

Insecure generation of random numbers In github.com/gofiber/utils/v2

Description

Fiber Utils UUIDv4 and UUID Silent Fallback to Predictable Values

Summary

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, the zero UUID "00000000-0000-0000-0000-000000000000". This compromises the security of all Fiber applications using these functions for security-critical operations on Go versions prior to 1.24.

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

Note: Go 1.24 and later panics on crypto/rand Read() failures, mitigating this vulnerability. Applications running on Go 1.24+ are not affected by the silent fallback behavior.


Vulnerability Details

Affected Functions

    Package: github.com/gofiber/utils

    Functions: UUIDv4() and UUID()

    Return Type: string (both functions)

    Locations: common.go:93-99 (UUIDv4), common.go:60-89 (UUID)

Technical Description

The vulnerability occurs through two related but distinct failure paths, both ultimately caused by crypto/rand.Read() failures on Go < 1.24:

Primary Path: UUIDv4() Vulnerability

    UUIDv4() calls google/uuid.NewRandom() which internally uses crypto/rand.Read()

    If uuid.NewRandom() fails, UUIDv4() falls back to the internal UUID() function

    No error is returned to the application - silent security failure occurs

Secondary Path: UUID() Vulnerability

    UUID() directly calls crypto/rand.Read(uuidSeed[:]) to seed its internal state

    If seeding fails, UUID() silently fails and returns the zero UUID "00000000-0000-0000-0000-000000000000"

    Applications receive predictable UUIDs with no indication of the security failure


Code Analysis

UUIDv4() Vulnerability Path

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()
}

UUID() Vulnerability Path

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 {...

Root Cause: Both vulnerabilities stem from crypto/rand.Read() failures, occurring through different code paths with the same dangerous silent fallback behavior.


Security Impact

Severity: CRITICAL

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 (the zero UUID), resulting in:

    Session fixation / universal session hijack

    CSRF token predictability and bypass

    Authentication token replay

    Global identifier collisions leading to severe application breakage

    Potential application-wide DoS due to every request using the same “unique” key, causing cache overwrites, session stomping, corrupted internal maps, and loss of isolation across all users


Attack Scenario

While entropy exhaustion is extremely rare on modern Linux systems, RNG access failures (e.g., restricted /dev/random or /dev/urandom access, broken container environments, sandbox restrictions, misconfigured VMs, or FIPS-mode RNG failures) are realistic. In these scenarios on Go < 1.24, crypto/rand may return errors immediately — triggering the vulnerable fallback paths.

On Go 1.24+, crypto/rand Read() panics on failure, mitigating the silent-zero fallback issue.


Proof of Concept

    uuid.NewRandom() fails (indirect crypto/rand.Read() failure)

    UUIDv4() calls UUID() as fallback with no error returned

    UUID() seeding fails directly via crypto/rand.Read(uuidSeed[:])

    Zero UUID "00000000-0000-0000-0000-000000000000" is returned silently

    No error is propagated to the application from either function


Affected Versions

    All versions of github.com/gofiber/utils containing the UUIDv4() or UUID() functions

    Applications using Fiber middleware that depend on UUIDv4() or UUID for security

    Only applicable to Go < 1.24; Go 1.24+ panics/block on crypto/rand Read() failures and is not affected


Mitigation

Immediate Workaround

Replace usage of utils.UUIDv4() with uuid.New() or wait for fix:

sessionID := uuid.New()

Recommended Fix

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()
}
...

Detection

Applications can detect if they're affected by:

    Checking if they use github.com/gofiber/utils

    Searching for UUIDv4() and UUID() usage in security-critical code paths

    Reviewing Fiber middleware configurations that rely on defaults of UUIDv4() for security identifiers


References


Contact

Reported by: @sixcolors


Classification

    OWASP: A02:2021 - Cryptographic Failures

    Impact: Complete compromise of application security model on Go < 1.24

    Exploitability: Medium (requires entropy failure)

    Scope: All Fiber applications using affected middleware on Go < 1.24

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Component
Affected version
Patched versions
FLAT-PAEPS – Vulnerability | Fluid Attacks Database