Rate limiting has been implemented for donation-related endpoints to prevent abuse and accidental overload. The rate limiter enforces safe request limits while ensuring normal user activity is not impacted.
The rate limiting functionality is implemented in src/middleware/rateLimiter.js using the express-rate-limit package.
Rate limiting is applied only to donation operation endpoints:
POST /donations- Create a new donationPOST /donations/send- Send XLM and record donation
Limits:
- 10 requests per minute per IP address
- Stricter limit due to write operations and blockchain interactions
POST /donations/verify- Verify a transaction by hash
Limits:
- 30 requests per minute per IP address
- More lenient since verification is primarily a read operation
The following endpoints are NOT rate limited to ensure read operations remain fast:
GET /donations- List all donationsGET /donations/:id- Get specific donationGET /donations/recent- Get recent donationsGET /donations/limits- Get donation limitsPATCH /donations/:id/status- Update donation status- All wallet, stats, and stream endpoints
When rate limit is exceeded, the API returns:
- HTTP 429 (Too Many Requests)
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many donation requests from this IP. Please try again later.",
"retryAfter": "2024-01-15T10:30:00.000Z"
}
}The following standard headers are included:
RateLimit-Limit- Maximum requests allowed in the windowRateLimit-Remaining- Requests remaining in current windowRateLimit-Reset- Time when the rate limit resets (Unix timestamp)
The rate limiter is integrated with the idempotency middleware:
- Requests that are served from the idempotency cache do NOT count toward the rate limit
- This prevents legitimate retry attempts from being blocked
- Only new requests consume rate limit quota
Rate limiting is applied in the correct order:
- Rate limiter (first check)
- API key validation (if required)
- Idempotency check (if required)
- Permission check (if required)
- Business logic
To modify rate limits, edit src/middleware/rateLimiter.js:
const donationRateLimiter = rateLimit({
windowMs: 60 * 1000, // Time window in milliseconds
max: 10, // Maximum requests per window
// ... other options
});Different rate limiters can be applied to different endpoints:
donationRateLimiter- For creation operations (stricter)verificationRateLimiter- For verification operations (more lenient)
# Test donation creation rate limit (should fail after 10 requests)
for i in {1..15}; do
curl -X POST http://localhost:3000/donations \
-H "Content-Type: application/json" \
-H "X-API-Key: your-api-key" \
-H "Idempotency-Key: test-$i" \
-d '{"amount": 10, "recipient": "GXXX..."}'
echo "Request $i"
sleep 1
done- Requests 1-10: Success (200/201 status)
- Requests 11+: Rate limited (429 status)
- After 60 seconds: Rate limit resets, requests succeed again
- Rate limits are applied per IP address
- Protects against single-source abuse
- Does not prevent distributed attacks (consider additional DDoS protection)
- Rate limit is enforced before authentication
- Cannot be bypassed with different API keys from same IP
- Idempotency cache hits don't consume quota (prevents legitimate retries from being blocked)
- Consider implementing user-based rate limiting in addition to IP-based
- Monitor rate limit metrics to adjust thresholds
- Implement alerting for sustained rate limit violations
- Consider using Redis for distributed rate limiting in multi-server deployments
- Number of rate-limited requests per endpoint
- IPs frequently hitting rate limits
- Average requests per minute per endpoint
- Rate limit reset frequency
Rate limit violations are automatically logged by the middleware. Monitor logs for patterns:
[RateLimit] IP 192.168.1.1 exceeded limit on POST /donations
Potential improvements for consideration:
- User/account-based rate limiting (in addition to IP)
- Dynamic rate limits based on user tier or reputation
- Redis-backed rate limiting for distributed systems
- Configurable limits via environment variables
- Rate limit exemptions for trusted IPs
- Exponential backoff for repeated violations
express-rate-limit(^7.x) - Rate limiting middleware for Express