# RCA Report: CVE-2026-30246 — Fiber v3 Cache Middleware Key Collision

## Summary

In `github.com/gofiber/fiber/v3` versions `<= 3.1.0`, the default `KeyGenerator` of the `cache` middleware returns only `c.Path()`, ignoring the query string and all other request dimensions. This causes cache key collisions for requests to the same path with different query parameters (e.g., `/?id=1` vs `/?id=2`). The second request receives the first request's cached response, leading to cross-user information disclosure and cache confusion (CWE-200 / CWE-524).

## Impact

- **Package**: `github.com/gofiber/fiber/v3` (Go module)
- **Affected versions**: `<= 3.1.0`
- **Fixed version**: `3.2.0`
- **Severity**: Medium (CVSS 3.1 base 6.5)
- **Consequences**: Any application using the default cache middleware without a custom `KeyGenerator` is vulnerable to cache confusion. Responses tailored to one user's query parameters may be leaked to another user requesting the same path with different parameters.

## Root Cause

The vulnerable code in `middleware/cache/config.go` at v3.1.0 defines the default `KeyGenerator` as:

```go
KeyGenerator: func(c fiber.Ctx) string {
    return utils.CopyString(c.Path())
},
```

In `middleware/cache/cache.go`, the cache lookup key is built as:

```go
baseKey := cfg.KeyGenerator(c) + "_" + requestMethod
```

Because `c.Path()` returns only the URL path without the query string, requests to `/?id=1` and `/?id=2` both resolve to the same cache key (`/_GET`). The second request therefore hits the cached entry from the first request and receives the wrong response body.

The fix in v3.2.0 (commits `9a0d12c07ed895b84c72987f9288b04137afe5de` and `050ff1ff18511c1475b8ec627460216aaec627460216aaecddd4e`) completely rewrites the default key generator (`defaultKeyGenerator`) to include:
- HTTP method
- Escaped path (preventing delimiter injection)
- Canonical query string (sorted, with bounds to prevent DoS)
- Selected representation headers (`Accept`, `Accept-Encoding`, `Accept-Language`)
- Optional cookie dimensions

This ensures requests with different query parameters produce distinct cache keys, eliminating the collision.

## Reproduction Steps

1. Run `repro/reproduction_steps.sh`.
2. The script creates a scratch Go module, installs Fiber v3.1.0 (vulnerable) and v3.2.0 (fixed) separately, and for each version:
   - Builds a small Fiber server with the default `cache.New()` middleware.
   - Registers a handler on `/` that returns the `id` query parameter.
   - Issues `GET /?id=1` followed by `GET /?id=2`.
   - Captures the two response bodies to `logs/vulnerable_output.txt` and `logs/fixed_output.txt`.
3. **Expected evidence**:
   - **Vulnerable (v3.1.0)**: both responses are `1` (the second request hits the cache entry from the first because the query string is ignored in the key).
   - **Fixed (v3.2.0)**: responses are `1` then `2` (each request gets its own cache key because the query string is included).

## Evidence

- `logs/vulnerable_output.txt`:
  ```
  1
  1
  ```
- `logs/fixed_output.txt`:
  ```
  1
  2
  ```
- `logs/summary.txt`: contains the full run output with confirmation messages.
- `repro/runtime_manifest.json`: structured evidence with request/response pairs and verdict.

## Recommendations / Next Steps

1. **Upgrade immediately** to `github.com/gofiber/fiber/v3@v3.2.0` or later.
2. **If a custom `KeyGenerator` is in use**, audit it to ensure query strings, headers, or other user-specific dimensions are incorporated into the key.
3. **Regression test**: add an integration test that issues two requests to the same path with different query parameters and asserts distinct response bodies when caching is enabled.

## Additional Notes

- **Idempotency**: `repro/reproduction_steps.sh` was executed twice consecutively with identical results, confirming idempotency.
- **Edge cases**: The vulnerability is present regardless of the number or names of query parameters, as long as the path component remains identical. The default cache middleware only caches `GET` and `HEAD` requests, so other HTTP methods are not affected by this specific key collision.
