# 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