AntFleet

Anatomy · f1b5393a-0

Health endpoint exposes operational details (env var presence, raw DB error messages) to unauthenticated callers

highsecurityclosed in 4640404
repo ab4e09bc·PR #3·reviewed 2 weeks ago·closed 2 weeks ago

The vulnerable code

apps/web/app/api/health/route.ts:5-11

Code snippet unavailable. View on GitHub →

The reasoning

Opus

Health endpoint leaks which secrets are missing to unauthenticated callers

mediumsecurityhigh
  • apps/web/app/api/health/route.ts:17-26
  • apps/web/app/api/health/route.ts:53-57
The GET handler has no authentication and returns the `missing` array verbatim in the JSON response. A public, anonymous attacker hitting /api/health can enumerate exactly which production secrets are unset (e.g. ANTHROPIC_API_KEY, GITHUB_APP_WEBHOOK_SECRET, CRON_SECRET). This is a directly useful reconnaissance signal: knowing CRON_SECRET is unset means the cron endpoint can be invoked; knowing GITHUB_APP_WEBHOOK_SECRET is unset means webhook signature verification is likely disabled. Additionally the DB error string is echoed (err.message), which on connection failures typically contains the DB host, user, and sometimes credentials parsed from DATABASE_URL by pg/drizzle, leaking infra topology. Standard practice is to return a boolean ok/not-ok publicly and gate the detailed payload behind a shared secret (e.g. the existing CRON_SECRET) or an internal-only path.

Recommendation

Either (a) require an auth header (Bearer of CRON_SECRET or a dedicated HEALTH_TOKEN) before returning the detailed payload and otherwise return only `{ok}` with status, or (b) drop the `missing` array and `error` string from the public response and log them server-side instead.

GPT-5

Health endpoint exposes operational details (env var presence, raw DB error messages) to unauthenticated callers

highsecurityhigh
  • apps/web/app/api/health/route.ts:5-11
  • apps/web/app/api/health/route.ts:37-41
  • apps/web/app/api/health/route.ts:47-51
  • apps/web/app/api/health/route.ts:55-58
The health endpoint is publicly accessible and intended for external uptime checks. It returns a detailed JSON payload that includes an explicit list of missing environment variable names and a raw database error message. DB error messages can reveal internal infrastructure details (hosts, driver info) and the env.missing array confirms which secrets are configured. This is unnecessary information disclosure for unauthenticated callers and increases the attack surface. A minimal health check should avoid leaking internal state beyond an overall status code or a simple boolean, or require authentication for detailed diagnostics.

Recommendation

For unauthenticated requests in production, limit the response to a simple status (e.g., { ok: boolean } or just HTTP 200/503) and omit fields like env.missing and db.error. Optionally gate detailed diagnostics behind authentication (e.g., require a secret header, signed token, or internal allowlist), or only include details in non-production environments. At minimum, sanitize/replace DB error messages with a generic string and avoid enumerating missing env vars to the public.

The agreement

Both frontier models flagged this within the same line range. AntFleet's unanimous gate fired — the finding posted on the PR. Closed in 4640404.

The fix

Fix snippet unavailable. View on GitHub →

Closure

Closed 2 weeks ago

SHA: 4640404a33f71b499bcca5e4cf948ceaba5c7bc0

View closure receipt on GitHub →

Tweet thread template

tweet 1 of 8197 / 280

Two frontier models reviewed PR #3 on ab4e09bc. Both found this bug: high security: Health endpoint exposes operational details (env var presence, raw DB error messages) to unauthenticated callers

tweet 2 of 8123 / 280

The vulnerable code (apps/web/app/api/health/route.ts:5-11): (full snippet at https://www.antfleet.dev/anatomy/f1b5393a-0)

tweet 3 of 8280 / 280

What Opus saw: "The GET handler has no authentication and returns the `missing` array verbatim in the JSON response. A public, anonymous attacker hitting /api/health can enumerate exactly which production secrets are unset (e.g. ANTHROPIC_API_KEY, GITHUB_APP_WEBHOOK_SECRET, CRO…

tweet 4 of 8280 / 280

What GPT-5 saw: "The health endpoint is publicly accessible and intended for external uptime checks. It returns a detailed JSON payload that includes an explicit list of missing environment variable names and a raw database error message. DB error messages can reveal internal i…

tweet 5 of 897 / 280

Both flagged the same line range. AntFleet's unanimous gate fired — the finding posted on the PR.

tweet 6 of 893 / 280

The fix landed in commit 4640404: (view diff at https://www.antfleet.dev/anatomy/f1b5393a-0)

tweet 7 of 881 / 280

AntFleet reviews every PR with two frontier models. Only unanimous findings post.

tweet 8 of 877 / 280

Full anatomy + reasoning + diffs: https://www.antfleet.dev/anatomy/f1b5393a-0

Paste into X composer one tweet at a time. X has no multi-tweet intent API.