Skip to content

Commit 95dfa85

Browse files
1 parent f3ad088 commit 95dfa85

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

advisories/github-reviewed/2025/12/GHSA-m98w-cqp3-qcqr/GHSA-m98w-cqp3-qcqr.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-m98w-cqp3-qcqr",
4-
"modified": "2025-12-09T19:18:48Z",
4+
"modified": "2025-12-12T16:30:26Z",
55
"published": "2025-12-08T17:57:26Z",
66
"aliases": [
77
"CVE-2025-66565"
88
],
99
"summary": "Fiber Utils UUIDv4 and UUID Silent Fallback to Predictable Values",
10-
"details": "## Summary\n\nCritical 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.\n\n**Both functions are vulnerable to the same root cause (`crypto/rand` failure):**\n- `UUIDv4()`: Indirect vulnerability through `uuid.NewRandom()` → `crypto/rand.Read()` → fallback to `UUID()`\n- `UUID()`: Direct vulnerability through `crypto/rand.Read(uuidSeed[:])` → silent zero UUID return\n\n## Vulnerability Details\n\n### Affected Functions\n- **Package**: `github.com/gofiber/utils`\n- **Functions**: `UUIDv4()` and `UUID()`\n- **Return Type**: `string` (both functions)\n- **Locations**: `common.go:93-99` (UUIDv4), `common.go:60-89` (UUID)\n\n### Technical Description\n\nThe vulnerability occurs through two related but distinct failure paths, both ultimately caused by `crypto/rand.Read()` failures:\n\n#### Primary Path: UUIDv4() Vulnerability\n1. `UUIDv4()` calls `google/uuid.NewRandom()` which internally uses `crypto/rand.Read()`\n2. If `uuid.NewRandom()` fails due to entropy exhaustion, `UUIDv4()` falls back to the internal `UUID()` function\n3. **No error is returned to the application** - silent security failure occurs\n\n#### Secondary Path: UUID() Vulnerability\n1. `UUID()` directly calls `crypto/rand.Read(uuidSeed[:])` to seed its internal state\n2. If seeding fails, `UUID()` **silently fails** and returns the zero UUID `\"00000000-0000-0000-0000-000000000000\"`\n3. Applications receive predictable UUIDs with no indication of the security failure\n\n**Both functions are vulnerable to the same root cause (`crypto/rand` failure):**\n- `UUIDv4()`: Indirect vulnerability through `uuid.NewRandom()` → `crypto/rand.Read()` → fallback to `UUID()`\n- `UUID()`: Direct vulnerability through `crypto/rand.Read(uuidSeed[:])` → silent zero UUID return\n\n### Code Analysis\n\n#### UUIDv4() Vulnerability Path\n```go\n// Vulnerable code in UUIDv4() - Indirect rand.Read() failure\nfunc UUIDv4() string {\n\ttoken, err := uuid.NewRandom() // Uses crypto/rand.Read() internally\n\tif err != nil {\n\t\treturn UUID() // Dangerous fallback - no error returned to application\n\t}\n\treturn token.String()\n}\n```\n\n#### UUID() Vulnerability Path\n```go\n// Vulnerable fallback function UUID() - Direct rand.Read() failure\nfunc UUID() string {\n\tuuidSetup.Do(func() {\n\t\tif _, err := rand.Read(uuidSeed[:]); err != nil { // Direct crypto/rand.Read() call\n\t\t\treturn // Silent failure - no seeding, uuidCounter remains 0\n\t\t}\n\t\tuuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])\n\t})\n\tif atomic.LoadUint64(&uuidCounter) <= 0 {\n\t\treturn \"00000000-0000-0000-0000-000000000000\" // Zero UUID returned silently\n\t}\n\t// ... generate UUID from counter\n}\n```\n\n**Root Cause**: Both vulnerabilities stem from `crypto/rand.Read()` failures, but occur through different code paths with the same dangerous silent failure behavior.\n\n## Security Impact\n\n### Severity: CRITICAL\n\nThis 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:\n\n* **Session fixation / universal session hijack**\n* **CSRF token predictability and bypass**\n* **Authentication token replay**\n* **Global identifier collisions leading to severe application breakage**\n* **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\n\n### Attack Scenario\n\nImportantly, 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.\n\n### Real-World Impact\n\n* **Session fixation or hijacking** (predictable session IDs)\n* **CSRF token forging** or bypass\n* **Authentication replay / token prediction**\n* **Potential denial-of-service (DoS)** key-based structures (sessions, rate-limits, caches, CSRF token stores) collapse into a single shared key if the zero UUID is returned, causing widespread overwrite, lock contention, or state corruption\n* **Request-ID collisions**, undermining logging and trace integrity\n* **General compromise** of confidentiality, integrity, and authorization logic relying on UUIDs for uniqueness or secrecy\n\n## Proof of Concept\n\nThe vulnerability can be demonstrated by examining the fallback behavior in the source code. When `crypto/rand` fails:\n\n1. `uuid.NewRandom()` fails (indirect `crypto/rand.Read()` failure)\n2. `UUIDv4()` calls `UUID()` as fallback with no error returned\n3. `UUID()` seeding fails directly via `crypto/rand.Read(uuidSeed[:])`\n4. Zero UUID `\"00000000-0000-0000-0000-000000000000\"` is returned silently\n5. No error is propagated to the application from either function\n\nBoth `UUIDv4()` and `UUID()` exhibit the same dangerous silent failure behavior when `crypto/rand` is unavailable.\n\n## Affected Versions\n\n- All versions of `github.com/gofiber/utils` containing the `UUIDv4()` function\n- Applications using Fiber middleware that depend on `UUIDv4()` for security\n\n## Mitigation\n\n### Immediate Workaround\nReplace usage of `utils.UUIDv4()` with `uuid.New()` or wait for fix:\n\n```go\n// Instead of:\nsessionID := utils.UUIDv4()\n\n// Use:\nsessionID := uuid.New()\n```\n\n### Recommended Fix\nModify `utils.UUIDv4()` and `utils.UUID()`to fail explicitly when cryptographic randomness is unavailable:\n\n```go\nfunc UUIDv4() string {\n\ttoken, err := uuid.NewRandom()\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"utils: failed to generate secure UUID: %v\", err))\n\t}\n\treturn token.String()\n}\n```\n\n```go\nfunc UUID() string {\n uuidSetup.Do(func() {\n if _, err := rand.Read(uuidSeed[:]); err != nil {\n panic(fmt.Sprintf(\"utils: failed to seed UUID generator: %v\", err))\n }\n uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])\n })\n if atomic.LoadUint64(&uuidCounter) <= 0 {\n panic(\"utils: UUID generator not properly seeded\")\n }\n // ... generate UUID from counter\n}\n```\n\n## Detection\n\nApplications can detect if they're affected by:\n1. Checking if they use `github.com/gofiber/utils` package\n2. Searching for `UUIDv4()` usage in security-critical code paths\n3. Reviewing middleware configurations that use UUIDv4 as defaults\n\nor\n\n1. Checking to see if any Fiber middleware is used that relies on defaults of `UUIDv4()` for security identifiers.\n\n## Contact\n\nReported by: [@sixcolors](github.com/sixcolors)\n\n## Classification\n\n- **OWASP**: A02:2021 - Cryptographic Failures\n- **Impact**: Complete compromise of application security model\n- **Exploitability**: Medium (requires entropy exhaustion)\n- **Scope**: All Fiber applications using affected middleware",
10+
"details": "## Summary\n\nCritical 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**.\n\n**Both functions are vulnerable to the same root cause (`crypto/rand` failure):**\n\n* `UUIDv4()`: Indirect vulnerability through `uuid.NewRandom()` → `crypto/rand.Read()` → fallback to `UUID()`\n* `UUID()`: Direct vulnerability through `crypto/rand.Read(uuidSeed[:])` → silent zero UUID return\n\n> **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.\n\n---\n\n## Vulnerability Details\n\n### Affected Functions\n\n* **Package**: `github.com/gofiber/utils`\n* **Functions**: `UUIDv4()` and `UUID()`\n* **Return Type**: `string` (both functions)\n* **Locations**: `common.go:93-99` (UUIDv4), `common.go:60-89` (UUID)\n\n### Technical Description\n\nThe vulnerability occurs through two related but distinct failure paths, both ultimately caused by `crypto/rand.Read()` failures on Go < 1.24:\n\n#### Primary Path: UUIDv4() Vulnerability\n\n1. `UUIDv4()` calls `google/uuid.NewRandom()` which internally uses `crypto/rand.Read()`\n2. If `uuid.NewRandom()` fails, `UUIDv4()` falls back to the internal `UUID()` function\n3. **No error is returned to the application** - silent security failure occurs\n\n#### Secondary Path: UUID() Vulnerability\n\n1. `UUID()` directly calls `crypto/rand.Read(uuidSeed[:])` to seed its internal state\n2. If seeding fails, `UUID()` **silently fails** and returns the zero UUID `\"00000000-0000-0000-0000-000000000000\"`\n3. Applications receive predictable UUIDs with no indication of the security failure\n\n---\n\n### Code Analysis\n\n#### UUIDv4() Vulnerability Path\n\n```go\nfunc UUIDv4() string {\n\ttoken, err := uuid.NewRandom() // Uses crypto/rand.Read() internally\n\tif err != nil {\n\t\treturn UUID() // Dangerous fallback - no error returned to application\n\t}\n\treturn token.String()\n}\n```\n\n#### UUID() Vulnerability Path\n\n```go\nfunc UUID() string {\n\tuuidSetup.Do(func() {\n\t\tif _, err := rand.Read(uuidSeed[:]); err != nil { // Direct crypto/rand.Read() call\n\t\t\treturn // Silent failure - no seeding, uuidCounter remains 0\n\t\t}\n\t\tuuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])\n\t})\n\tif atomic.LoadUint64(&uuidCounter) <= 0 {\n\t\treturn \"00000000-0000-0000-0000-000000000000\" // Zero UUID returned silently\n\t}\n\t// ... generate UUID from counter\n}\n```\n\n**Root Cause:** Both vulnerabilities stem from `crypto/rand.Read()` failures, occurring through different code paths with the same dangerous silent fallback behavior.\n\n---\n\n## Security Impact\n\n### Severity: CRITICAL\n\nThis 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:\n\n* **Session fixation / universal session hijack**\n* **CSRF token predictability and bypass**\n* **Authentication token replay**\n* **Global identifier collisions leading to severe application breakage**\n* **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\n\n---\n\n### Attack Scenario\n\nWhile **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.\n\nOn **Go 1.24+**, `crypto/rand` `Read()` panics on failure, mitigating the silent-zero fallback issue.\n\n---\n\n### Proof of Concept\n\n1. `uuid.NewRandom()` fails (indirect `crypto/rand.Read()` failure)\n2. `UUIDv4()` calls `UUID()` as fallback with no error returned\n3. `UUID()` seeding fails directly via `crypto/rand.Read(uuidSeed[:])`\n4. Zero UUID `\"00000000-0000-0000-0000-000000000000\"` is returned silently\n5. No error is propagated to the application from either function\n\n---\n\n## Affected Versions\n\n* All versions of `github.com/gofiber/utils` containing the `UUIDv4()` or `UUID()` functions\n* Applications using Fiber middleware that depend on `UUIDv4()` or `UUID` for security\n* **Only applicable to Go < 1.24**; Go 1.24+ panics/block on `crypto/rand` `Read()` failures and is not affected\n\n---\n\n## Mitigation\n\n### Immediate Workaround\n\nReplace usage of `utils.UUIDv4()` with `uuid.New()` or wait for fix:\n\n```go\nsessionID := uuid.New()\n```\n\n### Recommended Fix\n\nModify `utils.UUIDv4()` and `utils.UUID()` to fail explicitly when cryptographic randomness is unavailable:\n\n```go\nfunc UUIDv4() string {\n\ttoken, err := uuid.NewRandom()\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"utils: failed to generate secure UUID: %v\", err))\n\t}\n\treturn token.String()\n}\n\nfunc UUID() string {\n uuidSetup.Do(func() {\n if _, err := rand.Read(uuidSeed[:]); err != nil {\n panic(fmt.Sprintf(\"utils: failed to seed UUID generator: %v\", err))\n }\n uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])\n })\n if atomic.LoadUint64(&uuidCounter) <= 0 {\n panic(\"utils: UUID generator not properly seeded\")\n }\n // ... generate UUID from counter\n}\n```\n\n---\n\n## Detection\n\nApplications can detect if they're affected by:\n\n1. Checking if they use `github.com/gofiber/utils`\n2. Searching for `UUIDv4()` and `UUID()` usage in security-critical code paths\n3. Reviewing Fiber middleware configurations that rely on defaults of `UUIDv4()` for security identifiers\n\n---\n\n## References\n\n* **Package Repository**: [https://github.com/gofiber/utils](https://github.com/gofiber/utils)\n* **Fiber Framework**: [https://github.com/gofiber/fiber](https://github.com/gofiber/fiber)\n* **Google UUID Library**: [https://github.com/google/uuid](https://github.com/google/uuid)\n* Golang `crypto/rand` behavior changes: [golang/go#66821](https://github.com/golang/go/issues/66821), [Go 1.25.5 source](https://cs.opensource.google/go/go/+/refs/tags/go1.25.5:src/crypto/rand/rand.go;l=80)\n\n---\n\n## Contact\n\nReported by: [@sixcolors](https://github.com/sixcolors)\n\n---\n\n## Classification\n\n* **OWASP**: A02:2021 - Cryptographic Failures\n* **Impact**: Complete compromise of application security model on Go < 1.24\n* **Exploitability**: Medium (requires entropy failure)\n* **Scope**: All Fiber applications using affected middleware on Go < 1.24",
1111
"severity": [
1212
{
1313
"type": "CVSS_V4",
@@ -50,11 +50,14 @@
5050
"introduced": "0"
5151
},
5252
{
53-
"last_affected": "1.2.0"
53+
"fixed": "1.2.0"
5454
}
5555
]
5656
}
57-
]
57+
],
58+
"database_specific": {
59+
"last_known_affected_version_range": "<= 1.1.0"
60+
}
5861
}
5962
],
6063
"references": [

0 commit comments

Comments
 (0)