72 lines
1.7 KiB
Markdown
72 lines
1.7 KiB
Markdown
# UNDF: UNDF-2026-000000558
|
||
# traefik-0002 — Tracer.safeURL slices.Contains O(Q×P) per request
|
||
|
||
## Ecosystem
|
||
traefik (Go)
|
||
|
||
## Severity
|
||
MEDIUM — triggered on every traced HTTP request when safeQueryParams is configured
|
||
|
||
## Location
|
||
`pkg/observability/tracing/tracing.go`
|
||
Function: `safeURL`
|
||
|
||
## Description
|
||
`safeURL` is called on every traced HTTP request to redact query parameters
|
||
that are not in the safe list. For each of Q query parameters in the URL,
|
||
it calls `slices.Contains(t.safeQueryParams, k)` which is an O(P) linear scan:
|
||
|
||
```go
|
||
query := redactedURL.Query()
|
||
for k := range query { // O(Q) outer
|
||
if slices.Contains(t.safeQueryParams, k) { // O(P) inner scan
|
||
continue
|
||
}
|
||
query.Set(k, "REDACTED")
|
||
}
|
||
```
|
||
|
||
Complexity: O(Q × P) per traced request, where Q = query param count
|
||
and P = len(safeQueryParams).
|
||
|
||
`safeQueryParams` is fixed at construction time; it can be pre-built
|
||
into a `map[string]struct{}` making each lookup O(1).
|
||
|
||
## CWE
|
||
CWE-407: Inefficient Algorithmic Complexity
|
||
|
||
## Fix
|
||
|
||
### Tracer struct — add pre-built set
|
||
```go
|
||
type Tracer struct {
|
||
...
|
||
safeQueryParams []string // keep for config inspection
|
||
safeQueryParamsSet map[string]struct{} // pre-built O(1) lookup
|
||
...
|
||
}
|
||
```
|
||
|
||
### NewTracer — build set at construction
|
||
```go
|
||
safeQueryParamsSet := make(map[string]struct{}, len(safeQueryParams))
|
||
for _, p := range safeQueryParams {
|
||
safeQueryParamsSet[p] = struct{}{}
|
||
}
|
||
```
|
||
|
||
### safeURL — O(1) lookup
|
||
```go
|
||
for k := range query {
|
||
if _, ok := t.safeQueryParamsSet[k]; ok {
|
||
continue
|
||
}
|
||
query.Set(k, "REDACTED")
|
||
}
|
||
```
|
||
|
||
## Speedup
|
||
P=20 safe params, Q=30 query params: 20x reduction per request.
|
||
|
||
## Status
|
||
PATCHED (patch in this file)
|