Skip to content

Bound HTTP metrics route-label cardinality to prevent a metric-explosion DoS #558

Description

@mikewheeleer

Bound HTTP metrics route-label cardinality to prevent a metric-explosion DoS

Description

MetricsService.trackHttpRequest in src/observability/metrics-service.ts labels http_requests_total and http_request_duration_seconds with route = extractRoute(req). If extractRoute ever falls back to a raw URL/path (rather than the matched Express route template), then paths embedding identifiers — /contracts/abc, /contracts/def, … — each create a new Prometheus time series. An attacker hitting many distinct paths can blow up label cardinality, exhausting memory in the process and in the scraping Prometheus. This is distinct from existing header-redaction and per-provider-gauge work; it is specifically about the unbounded route label.

Requirements and context

  • Repository scope: Talenttrust/Talenttrust-Backend only.
  • Ensure extractRoute resolves to the matched route template (e.g. req.route?.path joined with baseUrl) and never the concrete path with embedded ids; collapse unmatched requests to a single unmatched bucket.
  • Add a hard cap on distinct route label values; once exceeded, attribute further routes to an other bucket so cardinality cannot grow without bound.
  • Keep method and status_code labels intact; do not change metric names.
  • Make the cap configurable via validated config in src/config/env.schema.ts.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b security/metrics-route-cardinality-cap
  • Implement changes
    • Write code in: src/observability/metrics-service.ts.
    • Write comprehensive tests in: create src/observability/metrics-service.test.ts — fire many distinct concrete paths and assert the number of route label values stays bounded and unmatched paths collapse.
    • Add documentation: note the cardinality guard in the observability/health section of README.md.
    • Add TSDoc to extractRoute and the cap logic.
    • Validate security: distinct user-controlled paths cannot create unbounded series.
  • Test and commit

Test and commit

  • Run npm run lint and npm test.
  • Cover edge cases: matched template, unmatched 404, cap boundary, high-cardinality flood.
  • Include the full npm test output and a security notes section in the PR.

Example commit message

fix(observability): bound HTTP metrics route-label cardinality

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • 💬 Join the TalentTrust community on Discord for questions, reviews, and faster merges: https://discord.gg/WqnGpcPx
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions