2b5b875dfe
BREAKING CHANGE: Server now requires JWT_SECRET environment variable to be set Security fixes: - Remove hardcoded JWT secret fallback 'your-secret-key' from protectedImages.js - Add startup validation to ensure JWT_SECRET is properly configured - Reject insecure default values and short secrets - Server will refuse to start without proper JWT_SECRET This fixes a critical vulnerability where the application would use a publicly known secret if JWT_SECRET was not set, completely compromising authentication. Migration guide: docs/JWT_SECRET_MIGRATION.md 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
98 lines
3.2 KiB
JavaScript
Executable File
98 lines
3.2 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Test script to verify JWT_SECRET validation works correctly
|
|
* This ensures our security fix doesn't break production
|
|
*/
|
|
|
|
const { spawn } = require('child_process');
|
|
const path = require('path');
|
|
|
|
console.log('=== Testing JWT_SECRET Validation ===\n');
|
|
|
|
// Test 1: Server should fail to start without JWT_SECRET
|
|
console.log('Test 1: Starting server without JWT_SECRET...');
|
|
const test1 = spawn('node', [path.join(__dirname, '..', 'server.js')], {
|
|
env: { ...process.env, JWT_SECRET: '' },
|
|
stdio: 'pipe'
|
|
});
|
|
|
|
let test1Output = '';
|
|
test1.stderr.on('data', (data) => {
|
|
test1Output += data.toString();
|
|
});
|
|
|
|
test1.on('close', (code) => {
|
|
if (code === 1 && test1Output.includes('Missing required environment variable: JWT_SECRET')) {
|
|
console.log('✅ Test 1 PASSED: Server correctly refuses to start without JWT_SECRET\n');
|
|
runTest2();
|
|
} else {
|
|
console.log('❌ Test 1 FAILED: Server should have failed to start');
|
|
console.log('Exit code:', code);
|
|
console.log('Output:', test1Output);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
|
|
// Test 2: Server should fail with insecure default value
|
|
function runTest2() {
|
|
console.log('Test 2: Starting server with insecure JWT_SECRET...');
|
|
const test2 = spawn('node', [path.join(__dirname, '..', 'server.js')], {
|
|
env: { ...process.env, JWT_SECRET: 'your-secret-key' },
|
|
stdio: 'pipe'
|
|
});
|
|
|
|
let test2Output = '';
|
|
test2.stderr.on('data', (data) => {
|
|
test2Output += data.toString();
|
|
});
|
|
|
|
test2.on('close', (code) => {
|
|
if (code === 1 && test2Output.includes('JWT_SECRET is set to the insecure default value')) {
|
|
console.log('✅ Test 2 PASSED: Server correctly refuses insecure JWT_SECRET\n');
|
|
runTest3();
|
|
} else {
|
|
console.log('❌ Test 2 FAILED: Server should have rejected insecure JWT_SECRET');
|
|
console.log('Exit code:', code);
|
|
console.log('Output:', test2Output);
|
|
process.exit(1);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Test 3: Verify protectedImages functions work with valid JWT_SECRET
|
|
function runTest3() {
|
|
console.log('Test 3: Testing protectedImages functions...');
|
|
|
|
// Set a valid JWT_SECRET for this test
|
|
process.env.JWT_SECRET = 'test-secret-key-that-is-long-enough-for-security';
|
|
|
|
try {
|
|
// Load the module to test
|
|
const protectedImagesPath = path.join(__dirname, '..', 'src', 'routes', 'protectedImages.js');
|
|
delete require.cache[protectedImagesPath]; // Clear cache to ensure fresh load
|
|
|
|
// This will throw if JWT_SECRET is not available
|
|
require(protectedImagesPath);
|
|
|
|
console.log('✅ Test 3 PASSED: protectedImages module loads successfully with valid JWT_SECRET\n');
|
|
|
|
console.log('=== All Tests Passed! ===');
|
|
console.log('\nThe JWT_SECRET validation is working correctly.');
|
|
console.log('Production systems must have JWT_SECRET set to a secure value.');
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.log('❌ Test 3 FAILED: Error loading protectedImages module');
|
|
console.log('Error:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Give the first test some time to complete
|
|
setTimeout(() => {
|
|
if (test1.exitCode === null) {
|
|
console.log('❌ Test 1 TIMEOUT: Server did not exit as expected');
|
|
test1.kill();
|
|
process.exit(1);
|
|
}
|
|
}, 5000); |