55 lines
2.7 KiB
Markdown
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
|