java-topology/whitepaper/outreach/consul.md

2.4 KiB
Raw Blame History

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

// 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:

// 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.