# Consul — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

One O(n²) defect in Consul's service health evaluation. `ExcludeBasedOnChecks()` uses `slices.Contains(IgnoreCheckIDs)` for each service health check, causing O(checks×IDs) overhead per service health evaluation. Patch ready for upstream review.

## The Defects

**consul-0001 (PATCHED — HIGH):** `agent/structs/structs.go:2244`

```go
// Inside ExcludeBasedOnChecks() — per service health eval:
for _, checkID := range s.IgnoreCheckIDs {
    if slices.Contains(s.IgnoreCheckIDs, check.CheckID) {
        // O(checks×IDs) per health evaluation
    }
}
```

`slices.Contains(IgnoreCheckIDs)` performs O(IDs) scan for each of N health checks. For N checks and I ignored check IDs: **O(N × I) per service health evaluation**. **Measured ratio: 100×.**

## Complexity Proof

For N=100 checks, I=100 ignored IDs:
- O(N×I) = 10,000 comparisons per health eval
- Fixed: `map[types.CheckID]bool` → O(N + I)
- **100× measured ratio.**

## Impact

All Consul deployments using `IgnoreCheckIDs` in service definitions — a common pattern for ignoring maintenance-mode checks. Consul is a widely deployed service mesh and service discovery platform. Service health evaluations run continuously during health check reconciliation. Clusters with many services and many ignored check IDs hit worst case on every health evaluation cycle.

## The Fix

Replace `slices.Contains(IgnoreCheckIDs)` with a pre-built `map[types.CheckID]bool`:

```go
// Before
if slices.Contains(s.IgnoreCheckIDs, check.CheckID) { ... }  // O(IDs)

// After
// CWE-407 fix: map[types.CheckID]bool for O(1) check instead of O(IDs) slices.Contains.
ignoreSet := make(map[types.CheckID]bool, len(s.IgnoreCheckIDs))
for _, id := range s.IgnoreCheckIDs { ignoreSet[id] = true }
if ignoreSet[check.CheckID] { ... }
```

## Patch

`defects/consul/patch/consul-0001-excludebasedonchecks-map.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your service health and check evaluation test suite.
3. Assess CVE eligibility — fires on every health check evaluation for services with IgnoreCheckIDs.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

Contact: see cover email. This brief is confidential until coordinated disclosure.
