# 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)
