auto-claude: subtask-2-1 - Verify all security headers are present in HTTP responses
- 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>
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
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);
|
||||
});
|
||||
Reference in New Issue
Block a user