Skip to content

feat(rate-limit): return 429 with Retry-After headers and safe-error …#313

Merged
mikewheeleer merged 1 commit into
Talenttrust:mainfrom
Abolax123:enhancement/rate-limit-429-headers
Jun 2, 2026
Merged

feat(rate-limit): return 429 with Retry-After headers and safe-error …#313
mikewheeleer merged 1 commit into
Talenttrust:mainfrom
Abolax123:enhancement/rate-limit-429-headers

Conversation

@Abolax123

Copy link
Copy Markdown

Closes #259

Overview

This PR implements RFC 6585 compliant 429 Too Many Requests responses with proper HTTP headers and alignment with the safe-error contract policy. When request limits are exceeded, the API now returns standards-compliant responses with Retry-After headers instead of generic errors that may leak internal state.

Problem Statement

  • Previous implementation returned 429 responses but with inconsistent, implementation-specific messages
  • Error messages exposed details about internal rate limiter state (e.g., "Abuse detected. Your access has been temporarily blocked")
  • Missing alignment with CWE-209 (Information Disclosure) prevention via safe-error policy
  • Documentation lacked RFC 6585 compliance details and client backoff guidance

Solution

Changes Made

1. src/middleware/rateLimiter.ts

  • ✅ Imported sanitizeErrorMessage from src/errors/safeErrors.ts
  • ✅ Updated all three 429 response paths to use safe-error contract
  • ✅ All responses now use consistent safe message: "Too many requests — please try again later"
  • ✅ Removed retryAfter field from response body (redundant with Retry-After header)
  • ✅ Ensured Retry-After header is always set when sending 429 response
  • ✅ Enhanced TSDoc with RFC 6585 compliance section

2. docs/request-limits-implementation.md

  • ✅ Added comprehensive "Rate Limiting (RFC 6585)" section
  • ✅ Documented 429 response format with headers
  • ✅ Provided client backoff guidance with JavaScript example
  • ✅ Updated monitoring, troubleshooting, and security sections

RFC 6585 Compliance

✅ HTTP 429 status for all rate limit responses
✅ Retry-After header (seconds format per RFC 6585)
✅ X-RateLimit-Limit header (max requests)
✅ X-RateLimit-Remaining header (requests left)
✅ X-RateLimit-Reset header (seconds until reset)
✅ X-RateLimit-Blocked header (true when hard-blocked)
✅ Safe error response body per error contract
✅ requestId for log correlation

Security

  • CWE-209 Mitigation: No internal state details leaked
  • Safe-Error Policy: Messages sanitized via sanitizeErrorMessage()
  • Consistent Responses: Prevent behavior inference attacks
  • No Secrets: All values generated from validated sources

Response Format

Headers

…contract

- Update src/middleware/rateLimiter.ts to return RFC 6585 compliant 429 responses
- All 429 responses now include Retry-After header as required by RFC 6585
- Standardize error responses to follow safe-error contract (CWE-209 compliance)
- Error messages are sanitized via sanitizeErrorMessage() to prevent info disclosure
- Consistent safe message: 'Too many requests — please try again later'
- X-RateLimit-* headers continue to reflect rate limit state
- X-RateLimit-Blocked header indicates when client is hard-blocked
- Improve documentation in docs/request-limits-implementation.md with:
  - RFC 6585 compliance details
  - 429 response format specification
  - Client backoff guidance and retry examples
  - Updated test coverage requirements

Security notes:
- No internal limiter state leaks to clients
- Error messages remain consistent regardless of block reason
- requestId enables client-server log correlation
- Aligned with safe-error policy to prevent CWE-209 vulnerabilities
@drips-wave

drips-wave Bot commented May 31, 2026

Copy link
Copy Markdown

@Abolax123 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@mikewheeleer mikewheeleer merged commit 7de9b83 into Talenttrust:main Jun 2, 2026
2 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Return RFC 6585 429 responses with Retry-After from rateLimit middleware

2 participants