diff --git a/services/09-commerce-engine/security.test.js b/services/09-commerce-engine/security.test.js index 2da67a08b..4911cc1eb 100644 --- a/services/09-commerce-engine/security.test.js +++ b/services/09-commerce-engine/security.test.js @@ -93,4 +93,38 @@ describe('L9 Commerce Engine Security Tests', () => { ); }); }); + + describe('JWT Weak Secret Production Rejection', () => { + const originalEnv = process.env.NODE_ENV; + const originalJwtSecret = process.env.JWT_SECRET; + + afterEach(() => { + process.env.NODE_ENV = originalEnv; + process.env.JWT_SECRET = originalJwtSecret; + }); + + test('should return 500 in production when weak secret is used in auth middleware', async () => { + process.env.NODE_ENV = 'production'; + process.env.JWT_SECRET = 'dev_secret_change_in_production'; + + const { authenticateToken } = require('./src/utils/auth'); + + const req = { + headers: { + authorization: `Bearer ${fleetAToken}` + } + }; + const res = { + status: jest.fn().mockReturnThis(), + json: jest.fn() + }; + const next = jest.fn(); + + authenticateToken(req, res, next); + + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith({ error: 'Internal server configuration error' }); + expect(next).not.toHaveBeenCalled(); + }); + }); }); diff --git a/services/09-commerce-engine/src/utils/auth.js b/services/09-commerce-engine/src/utils/auth.js index 407f8a08a..4f09af2c6 100644 --- a/services/09-commerce-engine/src/utils/auth.js +++ b/services/09-commerce-engine/src/utils/auth.js @@ -1,5 +1,12 @@ const jwt = require('jsonwebtoken'); -const { jwtSecret } = require('../../config'); +const config = require('../../config'); + +const WEAK_SECRETS = ['dev_secret_change_in_production', 'test_secret', 'dev_secret', 'default_secret', 'secret']; + +const isWeakSecret = (secret) => { + if (!secret) return true; + return WEAK_SECRETS.includes(secret.toLowerCase().trim()); +}; const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; @@ -9,12 +16,20 @@ const authenticateToken = (req, res, next) => { return res.status(401).json({ error: 'Access token required' }); } - if (!jwtSecret || jwtSecret === 'dev_secret_change_in_production') { + const activeSecret = process.env.JWT_SECRET || config.jwtSecret; + + if (!activeSecret) { console.error('[Security] JWT_SECRET is not properly configured.'); return res.status(500).json({ error: 'Internal server configuration error' }); } - jwt.verify(token, jwtSecret, (err, user) => { + // [Security Hardening] Reject weak secrets in production environment + if (process.env.NODE_ENV === 'production' && isWeakSecret(activeSecret)) { + console.error('[Security] JWT_SECRET is weak, insecure, or default. Blocking authenticated endpoint access in production.'); + return res.status(500).json({ error: 'Internal server configuration error' }); + } + + jwt.verify(token, activeSecret, (err, user) => { if (err) { return res.status(403).json({ error: 'Invalid or expired token' }); }