Files
picpeak/backend/scripts/test-jwt-validation.js
T
paul 2b5b875dfe
Test Gitea Actions / test (push) Successful in 20s
continuous-integration/drone/push Build is passing
fix(security): remove hardcoded JWT secret fallback - CRITICAL
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>
2025-07-12 23:33:22 +02:00

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);