Files
Kordant/tasks/security-fixes/04-fix-rate-limit-substring-bypass.md
2026-05-29 09:03:47 -04:00

55 lines
2.7 KiB
Markdown

# 04. Fix rate limit bypass via incomplete sensitive path list
meta:
id: security-fixes-04
feature: security-fixes
priority: P1
depends_on: []
tags: [implementation, tests-required, medium-severity]
objective:
- Prevent resource exhaustion by replacing substring-based rate limiting with exact procedure name matching and a complete sensitive operation list
deliverables:
- Updated rate limiter in `web/src/server/api/utils.ts` using exact procedure name matching
- Expanded sensitive procedure list covering darkwatch, voiceprint, and other expensive operations
- Unit tests for rate limit matching logic
steps:
1. Examine the rate limiter at `web/src/server/api/utils.ts:35-38` (substring matching on `sensitivePaths`)
2. Review the tRPC router definitions to identify all expensive procedures:
- `darkwatch.runScan` (external API calls: HIBP, SecurityTrails, Censys, Shodan)
- `voiceprint.analyzeAudio` (300MB+ memory per request)
- Any other CPU/memory/network-intensive procedures
3. Replace `sensitivePaths.some(p => path.includes(p))` with exact procedure name matching using a `Set` of full procedure paths (e.g., `darkwatch.runScan`)
4. Define appropriate rate limits per procedure category:
- Auth operations: 3/hr (existing)
- Darkwatch scans: 5/hr (expensive external API calls)
- VoicePrint analysis: 10/hr (high memory usage)
- Default protected: 100/min (existing)
5. Update `protectedProcedure` configuration at `web/src/server/api/utils.ts:23-28` if needed
tests:
- Unit: Exact procedure name matching correctly identifies `darkwatch.runScan` as sensitive
- Unit: Substring attacks like `darkwatch.runScanLike` do not trigger sensitive tier
- Unit: `voiceprint.analyzeAudio` is classified as sensitive
- Unit: Auth procedures (`login`, `signup`) still match the sensitive tier
- Integration: Rapid fire requests to `darkwatch.runScan` are rate-limited at the sensitive tier
acceptance_criteria:
- Rate limiter uses exact procedure name matching (not substring)
- All expensive procedures are in the sensitive operation list
- Different sensitive procedures can have different rate limits
- Existing rate limits for auth operations are preserved
- No false positives from substring matching
validation:
- `cd web && bun test` — all tests pass
- Send rapid requests to `darkwatch.runScan` and verify rate limiting kicks in at the sensitive tier
- Verify `darkwatch.runScanLike` (non-existent) does not trigger sensitive tier
notes:
- Finding p8-004: The current substring heuristic (`path.includes(p)`) is too broad and incomplete
- Consider a tiered approach: `sensitive` (3/hr), `expensive` (10/hr), `standard` (100/min)
- Review all router definitions to ensure no new expensive procedures are missed