-
Notifications
You must be signed in to change notification settings - Fork 0
Add rate limiting, CSRF protection, idempotency keys, and error boundaries #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nd error boundaries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements comprehensive security hardening for the referral API, adding rate limiting, CSRF protection, idempotency keys, and error boundaries. The changes prepare the application for production use by preventing abuse, protecting against cross-site attacks, and handling duplicate submissions gracefully.
Key Changes:
- Added rate limiting via Upstash Redis with graceful fallback (5 requests per 60 seconds per IP)
- Implemented CSRF validation using Sec-Fetch-Site and Origin/Host header checking
- Added idempotency key support to prevent duplicate referral submissions on retry
- Created custom error boundaries and 404 page for better error handling
- Fixed memory leak in useToast hook by correcting the useEffect dependency array
Reviewed changes
Copilot reviewed 24 out of 26 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/api/referral/route.ts | Added CSRF validation, rate limiting, and idempotency checks to POST endpoint |
| src/lib/rate-limit.ts | Implements Upstash Redis-based sliding window rate limiter with graceful degradation |
| src/lib/idempotency.ts | Provides Redis-backed idempotency key caching with 24-hour TTL |
| src/lib/csrf.ts | Validates request origin using Sec-Fetch-Site and Origin headers |
| src/lib/db.ts | Added server-only import to prevent client-side bundling |
| src/services/referral.ts | Added server-only import to prevent client-side bundling |
| src/services/email.ts | Added server-only import to prevent client-side bundling |
| src/components/referral/referral-form.tsx | Generates UUID idempotency key for each submission |
| src/hooks/use-toast.ts | Fixed memory leak by removing state from useEffect dependency array |
| src/app/error.tsx | Root-level error boundary with styled error page |
| src/app/(protected)/error.tsx | Protected routes error boundary with database-specific messaging |
| src/app/not-found.tsx | Custom 404 page matching application design system |
| next.config.js | Added security headers (X-Frame-Options, HSTS, CSP-related headers) |
| test/api/referral-route.test.ts | Added comprehensive tests for POST endpoint security features |
| test/services/email.test.ts | New test suite for email service with 3 test cases |
| test/services/referral.test.ts | Added tests for batch operations and updateReferralRedeemed |
| test/mocks/*.ts | Created mock implementations for rate limiter, idempotency, CSRF, and email transport |
| package.json | Added @upstash/ratelimit and @upstash/redis dependencies |
| .env.local.example | Added environment variables for Upstash Redis configuration |
| src/schema/index.ts | Removed unused barrel file |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 48 out of 50 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
af6cb79 to
13172fa
Compare
PR 17: Security Hardening
This PR adds security infrastructure and production readiness for the referral API before developer onboarding.
Changes
Prisma Migrations replaces
db pushworkflow. Initial migration created, CI workflow updated with MySQL service container. Team workflow:npx prisma migrate devfor development,npx prisma migrate deployfor CI/production.Schema Updates adds
@uniqueconstraint onreferralCodeto prevent duplicates andupdatedAtfield with@updatedAtfor audit tracking.Rate Limiting protects POST
/api/referralfrom spam (5 requests/60s per IP) and auth endpoint from brute force (5 attempts/15min per IP). Uses Upstash Redis sliding window, falls back gracefully when unavailable.CSRF Protection validates origin headers on POST requests. Checks
Sec-Fetch-Sitefirst, then falls back toOriginvsHostcomparison. Blocks cross-site requests with 403.Idempotency Keys prevent duplicate referral submissions on network retry. Client generates UUID, server caches response in Redis for 24 hours.
Error Boundaries catch React errors at root layout (
global-error.tsx) and protected route levels. Custom 404 page replaces Next.js default.Content-Security-Policy header added to
next.config.jsfor XSS defense-in-depth.Environment Validation via
src/env.tsfails fast on missing required variables at startup.Other Changes
.nvmrcfor Node version consistency/coverage/Test Coverage
Added 22 tests: POST endpoint, batch operations, email service, server actions, JSON date coercion. All 55 tests pass.
Files
New:
prisma/migrations/,src/app/global-error.tsx,src/env.ts,test/actions/referral.test.ts,.nvmrcModified:
prisma/schema.prisma,src/middleware.ts,src/app/api/referral/route.ts,src/components/referral/referral-form.tsx,next.config.js,.github/workflows/ci.yml,package.json,eslint.config.mjsDeleted:
src/schema/index.tsDesktop viewport of 404 page
Mobile viewport of 404 page
Note
Other error pages follow the same layout