Updated frameworks.
This commit is contained in:
197
docs/changes/security/JWT-SEC-FIX.md
Normal file
197
docs/changes/security/JWT-SEC-FIX.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# 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.authenticate` preHandler
|
||||
- ❌ **Mock plugin overrides** real authentication
|
||||
|
||||
## 🔧 **IMPLEMENTATION STRATEGY**
|
||||
|
||||
### **Phase 1: Replace Mock Authentication Plugin**
|
||||
**File**: `/backend/src/core/plugins/auth.plugin.ts`
|
||||
|
||||
**Current Implementation**:
|
||||
```javascript
|
||||
// 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:
|
||||
```javascript
|
||||
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:
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
```typescript
|
||||
// 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**:
|
||||
```bash
|
||||
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**:
|
||||
1. **Frontend Auth0 flow** should obtain valid JWT
|
||||
2. **Backend endpoints** should validate JWT against Auth0 JWKS
|
||||
3. **request.user** should contain real Auth0 user data (`sub`, `email`, etc.)
|
||||
4. **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:
|
||||
```javascript
|
||||
// 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**
|
||||
1. **Frontend**: User logs in via Auth0, receives JWT
|
||||
2. **API Requests**: JWT sent in `Authorization: Bearer <token>` header
|
||||
3. **Backend**: Validates JWT against Auth0 public keys (JWKS)
|
||||
4. **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:
|
||||
```javascript
|
||||
// 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
|
||||
Reference in New Issue
Block a user