Bearer API endpoints are rate-limited purely by shared IP, not by API key — one key can starve another #81

Open
opened 2026-09-01 00:07:14 -04:00 by jared · 0 comments
Owner

Severity: Medium

RateLimitMiddleware::checkIpRateLimit() keys its counter file solely on hash('sha256', $ip . '_' . $type) (~line 84), and $type is always 'api' for every Bearer endpoint. The session-based half of check() is a no-op for Bearer clients: session_start() with no session cookie sent creates a brand-new session on every request, so the session counter never accumulates — only the shared IP bucket (120 req/min per IP_API_LIMIT) actually governs Bearer traffic.

Impact: If two different API keys are both used from the same host/NAT egress IP (e.g. hwmonDaemon plus a separate automation/triage tool, or a compromised third key), they share ONE 120 req/min bucket. A chatty or misbehaving key can exhaust that shared bucket and 429 a completely unrelated legitimate key's traffic from the same IP — the rate limit doesn't actually isolate tenants the way per-key limiting would.

Fix: Key the rate-limit bucket for Bearer-authenticated requests by API key ID (available post-ApiKeyAuth) instead of, or in addition to, IP address, so distinct keys get isolated limits.

**Severity:** Medium `RateLimitMiddleware::checkIpRateLimit()` keys its counter file solely on `hash('sha256', $ip . '_' . $type)` (~line 84), and `$type` is always `'api'` for every Bearer endpoint. The session-based half of `check()` is a no-op for Bearer clients: `session_start()` with no session cookie sent creates a brand-new session on every request, so the session counter never accumulates — only the shared IP bucket (120 req/min per `IP_API_LIMIT`) actually governs Bearer traffic. **Impact:** If two different API keys are both used from the same host/NAT egress IP (e.g. hwmonDaemon plus a separate automation/triage tool, or a compromised third key), they share ONE 120 req/min bucket. A chatty or misbehaving key can exhaust that shared bucket and 429 a completely unrelated legitimate key's traffic from the same IP — the rate limit doesn't actually isolate tenants the way per-key limiting would. **Fix:** Key the rate-limit bucket for Bearer-authenticated requests by API key ID (available post-`ApiKeyAuth`) instead of, or in addition to, IP address, so distinct keys get isolated limits.
jared added the priority/mediumrate-limitingsecurity labels 2026-09-08 10:15:48 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/tinker_tickets#81