49 lines
2.9 KiB
Markdown
49 lines
2.9 KiB
Markdown
Phase: 8
|
||
Sequence: 004
|
||
Slug: rate-limit-substring-bypass
|
||
Verdict: VALID
|
||
Rationale: Rate limiting sensitive path detection uses substring matching (path.includes) with incomplete sensitive list; sensitive operations like darkwatch.runScan and voiceprint.analyzeAudio get standard tier (100/min) instead of stricter limits
|
||
Severity-Original: medium
|
||
Severity: medium
|
||
PoC-Status: pending
|
||
Pre-FP-Flag: none
|
||
Debate: piolium/attack-surface/balanced-chamber-summary.md
|
||
|
||
## Summary
|
||
The rate limiting middleware in `web/src/server/api/utils.ts` detects sensitive paths using `path.includes(p)` where `p` is from a hardcoded list of sensitive operation names (`["login", "signup", "forgotPassword", "resetPassword"]`). This substring matching is imprecise and the sensitive list is incomplete — it only covers auth-related operations. Sensitive operations like `darkwatch.runScan` (triggers expensive external API calls), `voiceprint.analyzeAudio` (processes audio through ML), and `spamshield.classifySMS` get the standard `authenticated` tier (100/min) instead of a stricter `sensitive` tier (3/hr).
|
||
|
||
## Location
|
||
- `web/src/server/api/utils.ts` lines 35–38 (rate limiting middleware)
|
||
|
||
## Attacker Control
|
||
Any authenticated user can call sensitive operations at the higher rate limit (100/min) since they are not in the sensitive path list. The attacker does not need to craft special procedure paths — they simply use normal operations that are not covered by the sensitive list.
|
||
|
||
## Trust Boundary Crossed
|
||
Rate limiting policy boundary. The rate limiter applies different limits based on operation sensitivity, and the incomplete sensitive list allows operations that should be rate-limited to proceed at higher rates.
|
||
|
||
## Impact
|
||
Resource exhaustion and cost abuse for sensitive operations:
|
||
- `darkwatch.runScan` can be called 100 times/min instead of 3/hr, triggering expensive external API calls (HIBP, SecurityTrails, Censys, Shodan)
|
||
- `voiceprint.analyzeAudio` can be called 100 times/min, consuming memory and CPU for ML processing
|
||
- Service disruption for other users on the same server
|
||
|
||
## Evidence
|
||
```typescript
|
||
const sensitivePaths = ["login", "signup", "forgotPassword", "resetPassword"];
|
||
const effectiveTier = sensitivePaths.some((p) => path.includes(p)) ? "sensitive" : tier;
|
||
```
|
||
|
||
## Reproduction Steps
|
||
1. Authenticated user calls `darkwatch.runScan` with a watchlist item
|
||
2. The procedure path `"darkwatch.runScan"` does not contain any sensitive path substring
|
||
3. Rate limiter assigns `authenticated` tier (100/min) instead of `sensitive` tier (3/hr)
|
||
4. User can trigger 100 scans per minute, each triggering 5+ external API calls
|
||
5. Cumulative cost and resource impact affects all users
|
||
|
||
## Defense Search Results
|
||
- `path.includes(p)` substring matching is imprecise
|
||
- Sensitive list only covers auth-related operations
|
||
- `rateLimitedProcedure` middleware is not applied to all procedures
|
||
- No default sensitive tier for write operations (mutations)
|
||
- No IP-based rate limiting as secondary dimension
|