feat(security): add per-endpoint API rate limiting with Redis sliding window

Implement @EndpointRateLimit() decorator and EndpointRateLimitGuard for
granular per-endpoint rate limiting using a Redis sorted-set sliding window.
This prevents brute force attacks on auth endpoints, replay attacks on
payment callbacks, and scraping on search endpoints.

Applied rate limits:
- /auth/login: 5 req/min per IP
- /auth/register: 3 req/min per IP
- /listings POST: 10 req/min per user
- /search: 30 req/min per user
- /payments/callback/*: 100 req/min per IP

Features:
- True sliding window (sorted set) for accurate rate measurement
- Configurable key strategy (IP or authenticated user)
- Admin bypass support (enabled by default)
- Fail-open on Redis errors
- Proper 429 response with Retry-After header
- Rate limit headers (X-RateLimit-Limit/Remaining/Reset)
- 22 unit tests covering all scenarios

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-11 00:36:35 +07:00
parent f27b13f712
commit d824d16760
8 changed files with 777 additions and 4 deletions

View File

@@ -20,6 +20,12 @@ export {
type UserRateLimitOptions,
} from './guards/user-rate-limit.guard';
export { UserRateLimit } from './decorators/user-rate-limit.decorator';
export {
EndpointRateLimit,
ENDPOINT_RATE_LIMIT_KEY,
type EndpointRateLimitOptions,
} from './decorators/endpoint-rate-limit.decorator';
export { EndpointRateLimitGuard } from './guards/endpoint-rate-limit.guard';
export { FileValidationPipe } from './pipes/file-validation.pipe';
export type { FileValidationOptions, UploadedFile } from './pipes/file-validation.pipe';
export { validateEnv, validateJwtSecret } from './env-validation';