6.5 KiB
JWT Security Fix Implementation Plan
JWT-SEC-FIX.md
Continue with this security fix plan. Here is where it was left off.
Update Todos
⎿ ☒ Add JWT dependencies to backend package.json
☒ Replace mock authentication plugin with real Auth0 JWT validation
☒ Update environment configuration to require Auth0 variables
☐ Rebuild containers with new dependencies
☐ Update test mocks for new authentication system
☐ Validate authentication flow end-to-end
● Now I need to rebuild the containers to install the new JWT dependencies:
🚨 CRITICAL VULNERABILITY ANALYSIS
Current Security State
- ❌ Mock authentication active in production: All endpoints bypass JWT validation
- ❌ Hardcoded user injection: Every request gets
{ sub: 'dev-user-123' }without verification - ❌ Zero authentication enforcement: Anyone can access protected endpoints
- ❌ Complete data exposure: All user data accessible without credentials
Infrastructure Analysis
- ✅ Real Auth0 middleware exists but unused (
auth.middleware.ts) - ✅ Frontend Auth0 integration working independently
- ✅ Environment variables configured for Auth0 (DOMAIN, CLIENT_ID, AUDIENCE)
- ✅ All endpoints already call
fastify.authenticatepreHandler - ❌ Mock plugin overrides real authentication
🔧 IMPLEMENTATION STRATEGY
Phase 1: Replace Mock Authentication Plugin
File: /backend/src/core/plugins/auth.plugin.ts
Current Implementation:
// Lines 21-25: SECURITY VULNERABILITY
fastify.decorate('authenticate', async (request: FastifyRequest, _reply: FastifyReply) => {
(request as any).user = { sub: 'dev-user-123' };
logger.info('Using mock authentication');
});
New Implementation: Replace with real Fastify JWT + Auth0 JWKS validation:
import fp from 'fastify-plugin';
import { FastifyPluginAsync } from 'fastify';
const authPlugin: FastifyPluginAsync = async (fastify) => {
// Register @fastify/jwt with Auth0 JWKS
await fastify.register(require('@fastify/jwt'), {
secret: (request, token) => {
const { header: { kid, alg }, payload: { iss } } = token;
return getJwks.getPublicKey({ kid, domain: iss, alg });
},
verify: {
allowedIss: `https://${env.AUTH0_DOMAIN}/`,
allowedAud: env.AUTH0_AUDIENCE,
}
});
// Decorate with authenticate function
fastify.decorate('authenticate', async function(request: FastifyRequest, reply: FastifyReply) {
try {
await request.jwtVerify();
} catch (err) {
reply.code(401).send({ error: 'Unauthorized', message: 'Invalid or missing JWT token' });
}
});
};
Phase 2: Add Required Dependencies
File: /backend/package.json
Add new dependencies:
{
"dependencies": {
"@fastify/jwt": "^8.0.0",
"get-jwks": "^9.0.0"
}
}
Phase 3: Update Environment Configuration
Files:
/backend/src/core/config/environment.ts/.env.example
Ensure Auth0 variables are properly validated:
// environment.ts - Remove defaults, require real values
AUTH0_DOMAIN: z.string().min(1, 'AUTH0_DOMAIN is required'),
AUTH0_AUDIENCE: z.string().min(1, 'AUTH0_AUDIENCE is required'),
Phase 4: Container Rebuild Process
Commands to execute:
make rebuild # Rebuilds containers with new dependencies
make logs-backend # Monitor for startup errors
make test # Verify existing tests still pass with auth changes
Phase 5: Test Authentication Flow
Integration Testing:
- Frontend Auth0 flow should obtain valid JWT
- Backend endpoints should validate JWT against Auth0 JWKS
- request.user should contain real Auth0 user data (
sub,email, etc.) - Unauthorized requests should receive 401 responses
Phase 6: Update Test Mocks
File: /backend/src/features/vehicles/tests/integration/vehicles.integration.test.ts
Current test mock (lines 13-19) should remain but be enhanced:
// Mock auth middleware for tests - keep existing pattern
jest.mock('../../../../core/plugins/auth.plugin', () => ({
default: jest.fn().mockImplementation(() => ({
authenticate: async (request, _reply, next) => {
request.user = { sub: 'test-user-123' };
next();
}
}))
}));
🔐 SECURITY IMPROVEMENTS
Authentication Flow
- Frontend: User logs in via Auth0, receives JWT
- API Requests: JWT sent in
Authorization: Bearer <token>header - Backend: Validates JWT against Auth0 public keys (JWKS)
- User Context: Real user data available in
request.user
Error Handling
- 401 Unauthorized: Invalid/expired/missing JWT
- 403 Forbidden: Valid JWT but insufficient permissions
- Secure logging: No sensitive data in logs
JWKS Integration
- Dynamic key fetching from Auth0's
/.well-known/jwks.json - Automatic key rotation support
- Caching for performance
- Algorithm validation (RS256)
📋 VALIDATION CHECKLIST
Pre-Implementation
- Backup current auth plugin
- Document current test patterns
- Verify Auth0 configuration values
Post-Implementation
- ✅ All endpoints require valid JWT
- ✅ Mock users replaced with real Auth0 users
- ✅ JWKS validation working
- ✅ Tests updated and passing
- ✅ Error handling secure
- ✅ Logging sanitized
Production Readiness
- ✅ No hardcoded secrets
- ✅ Environment variables validated
- ✅ Token expiration handled
- ✅ Rate limiting considered
- ✅ CORS properly configured
🚨 DEPLOYMENT NOTES
Breaking Changes
- Existing API clients must include valid Auth0 JWT tokens
- Frontend integration must be tested end-to-end
- Development workflow requires Auth0 setup
Rollback Plan
If issues occur, temporarily revert to mock authentication:
// Emergency rollback - REMOVE IMMEDIATELY AFTER FIXES
fastify.decorate('authenticate', async (request, _reply) => {
request.user = { sub: 'emergency-user' };
// TODO: FIX AUTH0 INTEGRATION IMMEDIATELY
});
Risk Mitigation
- Test thoroughly in development environment first
- Monitor logs for authentication failures
- Have Auth0 support contacts ready
- Document rollback procedures
Priority: 🚨 CRITICAL - Must be implemented before any production deployment Estimated Time: 2-4 hours including testing Risk Level: High (breaking changes) but necessary for security