- Created comprehensive verification documentation - Confirmed all 4 security headers are properly configured in next.config.ts: * Content-Security-Policy with comprehensive directives * Strict-Transport-Security (HSTS) with max-age=31536000 * Referrer-Policy set to strict-origin-when-cross-origin * Permissions-Policy restricting sensitive browser features - Headers follow Next.js documentation patterns and best practices - Note: Headers configured correctly for production deployment - Added verification script and investigation documentation Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
166 lines
4.6 KiB
JavaScript
166 lines
4.6 KiB
JavaScript
const { spawn, execSync } = require('child_process');
|
|
const http = require('http');
|
|
|
|
console.log('===========================================');
|
|
console.log('Security Headers Verification Script');
|
|
console.log('===========================================\n');
|
|
|
|
// Kill any process on port 3000
|
|
console.log('Step 1: Stopping any processes on port 3000...');
|
|
try {
|
|
if (process.platform === 'win32') {
|
|
execSync('for /f "tokens=5" %a in (\'netstat -aon ^| find ":3000" ^| find "LISTENING"\') do taskkill /F /PID %a', { stdio: 'ignore' });
|
|
} else {
|
|
execSync('lsof -ti:3000 | xargs kill -9', { stdio: 'ignore' });
|
|
}
|
|
console.log('✓ Stopped existing processes\n');
|
|
} catch (e) {
|
|
console.log('✓ No processes to stop\n');
|
|
}
|
|
|
|
// Clear .next directory
|
|
console.log('Step 2: Clearing build cache...');
|
|
try {
|
|
execSync('rm -rf .next', { stdio: 'inherit' });
|
|
console.log('✓ Build cache cleared\n');
|
|
} catch (e) {
|
|
console.log('! Could not clear cache (may not exist)\n');
|
|
}
|
|
|
|
// Start dev server
|
|
console.log('Step 3: Starting Next.js dev server...');
|
|
const server = spawn('npm', ['run', 'dev'], {
|
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
shell: true,
|
|
detached: false
|
|
});
|
|
|
|
let serverReady = false;
|
|
|
|
server.stdout.on('data', (data) => {
|
|
const output = data.toString();
|
|
if (output.includes('Local:') || output.includes('localhost:3000')) {
|
|
serverReady = true;
|
|
console.log('✓ Server is ready!\n');
|
|
}
|
|
});
|
|
|
|
server.stderr.on('data', (data) => {
|
|
// Ignore stderr for now
|
|
});
|
|
|
|
// Wait for server to be ready, then test
|
|
const maxWait = 60000; // 60 seconds
|
|
const startTime = Date.now();
|
|
const interval = setInterval(() => {
|
|
if (serverReady || (Date.now() - startTime > maxWait)) {
|
|
clearInterval(interval);
|
|
|
|
// Give it a few more seconds to fully initialize
|
|
setTimeout(() => {
|
|
testHeaders();
|
|
}, 5000);
|
|
}
|
|
}, 1000);
|
|
|
|
function testHeaders() {
|
|
console.log('Step 4: Testing security headers...');
|
|
console.log('=========================================\n');
|
|
|
|
const options = {
|
|
hostname: 'localhost',
|
|
port: 3000,
|
|
path: '/de',
|
|
method: 'HEAD'
|
|
};
|
|
|
|
const req = http.request(options, (res) => {
|
|
const headers = res.headers;
|
|
|
|
let passCount = 0;
|
|
let failCount = 0;
|
|
|
|
// Check Content-Security-Policy
|
|
console.log('Checking Content-Security-Policy...');
|
|
if (headers['content-security-policy']) {
|
|
console.log('✓ Content-Security-Policy found');
|
|
console.log(` Value: ${headers['content-security-policy'].substring(0, 60)}...\n`);
|
|
passCount++;
|
|
} else {
|
|
console.log('✗ Content-Security-Policy MISSING\n');
|
|
failCount++;
|
|
}
|
|
|
|
// Check Strict-Transport-Security
|
|
console.log('Checking Strict-Transport-Security...');
|
|
if (headers['strict-transport-security']) {
|
|
console.log('✓ Strict-Transport-Security found');
|
|
console.log(` Value: ${headers['strict-transport-security']}\n`);
|
|
passCount++;
|
|
} else {
|
|
console.log('✗ Strict-Transport-Security MISSING\n');
|
|
failCount++;
|
|
}
|
|
|
|
// Check Referrer-Policy
|
|
console.log('Checking Referrer-Policy...');
|
|
if (headers['referrer-policy']) {
|
|
console.log('✓ Referrer-Policy found');
|
|
console.log(` Value: ${headers['referrer-policy']}\n`);
|
|
passCount++;
|
|
} else {
|
|
console.log('✗ Referrer-Policy MISSING\n');
|
|
failCount++;
|
|
}
|
|
|
|
// Check Permissions-Policy
|
|
console.log('Checking Permissions-Policy...');
|
|
if (headers['permissions-policy']) {
|
|
console.log('✓ Permissions-Policy found');
|
|
console.log(` Value: ${headers['permissions-policy']}\n`);
|
|
passCount++;
|
|
} else {
|
|
console.log('✗ Permissions-Policy MISSING\n');
|
|
failCount++;
|
|
}
|
|
|
|
console.log('=========================================');
|
|
console.log(`Results: ${passCount}/4 security headers found`);
|
|
console.log('=========================================\n');
|
|
|
|
if (failCount > 0) {
|
|
console.log('All response headers:');
|
|
console.log(headers);
|
|
console.log('');
|
|
}
|
|
|
|
// Cleanup and exit
|
|
server.kill('SIGTERM');
|
|
setTimeout(() => {
|
|
server.kill('SIGKILL');
|
|
process.exit(passCount === 4 ? 0 : 1);
|
|
}, 2000);
|
|
});
|
|
|
|
req.on('error', (error) => {
|
|
console.error('✗ Error testing headers:', error.message);
|
|
server.kill('SIGTERM');
|
|
setTimeout(() => {
|
|
server.kill('SIGKILL');
|
|
process.exit(1);
|
|
}, 2000);
|
|
});
|
|
|
|
req.end();
|
|
}
|
|
|
|
// Handle script termination
|
|
process.on('SIGINT', () => {
|
|
console.log('\n\nStopping server...');
|
|
server.kill('SIGTERM');
|
|
setTimeout(() => {
|
|
server.kill('SIGKILL');
|
|
process.exit(1);
|
|
}, 2000);
|
|
});
|