fix(auth): remove hardcoded JWT fallback secret — fail fast on missing env var

The auth module fell back to a publicly-known secret string when JWT_SECRET
was unset, creating a critical authentication bypass risk. Both jwt.strategy.ts
and auth.module.ts now throw at startup if JWT_SECRET is missing.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 04:01:21 +07:00
parent 820e7e07a1
commit 402b5b6810
3 changed files with 14 additions and 3 deletions

View File

@@ -46,7 +46,7 @@ API_PORT=3000
NODE_ENV=development
# -----------------------------------------------------------------------------
# JWT / Auth
# JWT / Auth (REQUIRED — app will not start without JWT_SECRET)
# -----------------------------------------------------------------------------
JWT_SECRET=your_jwt_secret_change_me
JWT_EXPIRES_IN=15m

View File

@@ -39,7 +39,13 @@ const QueryHandlers = [GetProfileHandler, GetAgentByUserIdHandler];
CqrsModule,
PassportModule,
JwtModule.register({
secret: process.env['JWT_SECRET'] || 'goodgo-jwt-secret-change-in-production',
secret: (() => {
const secret = process.env['JWT_SECRET'];
if (!secret) {
throw new Error('JWT_SECRET environment variable is required');
}
return secret;
})(),
signOptions: { expiresIn: '15m' },
}),
],

View File

@@ -6,10 +6,15 @@ import { type JwtPayload } from '../services/token.service';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
const jwtSecret = process.env['JWT_SECRET'];
if (!jwtSecret) {
throw new Error('JWT_SECRET environment variable is required');
}
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env['JWT_SECRET'] || 'goodgo-jwt-secret-change-in-production',
secretOrKey: jwtSecret,
});
}