- 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>
119 lines
3.4 KiB
JavaScript
119 lines
3.4 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Security Headers Verification Script
|
|
* Validates that all required security headers are configured in next.config.ts
|
|
*/
|
|
|
|
import { readFileSync } from 'fs';
|
|
import { fileURLToPath } from 'url';
|
|
import { dirname, join } from 'path';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = dirname(__filename);
|
|
|
|
const REQUIRED_HEADERS = [
|
|
'Content-Security-Policy',
|
|
'Strict-Transport-Security',
|
|
'Referrer-Policy',
|
|
'Permissions-Policy'
|
|
];
|
|
|
|
const EXPECTED_VALUES = {
|
|
'Content-Security-Policy': {
|
|
directives: [
|
|
"default-src 'self'",
|
|
"script-src",
|
|
"style-src",
|
|
"font-src",
|
|
"img-src",
|
|
"connect-src",
|
|
"frame-ancestors",
|
|
"base-uri",
|
|
"form-action"
|
|
]
|
|
},
|
|
'Strict-Transport-Security': {
|
|
includes: ['max-age=31536000', 'includeSubDomains', 'preload']
|
|
},
|
|
'Referrer-Policy': {
|
|
value: 'strict-origin-when-cross-origin'
|
|
},
|
|
'Permissions-Policy': {
|
|
includes: ['geolocation=()', 'microphone=()', 'camera=()', 'payment=()', 'usb=()']
|
|
}
|
|
};
|
|
|
|
console.log('🔒 Security Headers Verification\n');
|
|
console.log('━'.repeat(60));
|
|
|
|
try {
|
|
const configPath = join(__dirname, 'next.config.ts');
|
|
const configContent = readFileSync(configPath, 'utf-8');
|
|
|
|
let allPassed = true;
|
|
|
|
for (const header of REQUIRED_HEADERS) {
|
|
const headerRegex = new RegExp(`key:\\s*['"]${header}['"]`, 'i');
|
|
const found = headerRegex.test(configContent);
|
|
|
|
if (found) {
|
|
console.log(`✅ ${header}: FOUND`);
|
|
|
|
// Additional validation
|
|
const expected = EXPECTED_VALUES[header];
|
|
if (expected) {
|
|
if (expected.directives) {
|
|
// Check CSP directives
|
|
const allDirectivesFound = expected.directives.every(directive =>
|
|
configContent.includes(directive)
|
|
);
|
|
if (allDirectivesFound) {
|
|
console.log(` ✓ All required CSP directives present`);
|
|
} else {
|
|
console.log(` ⚠ Some CSP directives may be missing`);
|
|
}
|
|
} else if (expected.includes) {
|
|
// Check if all required parts are included
|
|
const allPartsFound = expected.includes.every(part =>
|
|
configContent.includes(part)
|
|
);
|
|
if (allPartsFound) {
|
|
console.log(` ✓ All required parts present`);
|
|
} else {
|
|
console.log(` ⚠ Some required parts may be missing`);
|
|
}
|
|
} else if (expected.value) {
|
|
// Check exact value
|
|
if (configContent.includes(expected.value)) {
|
|
console.log(` ✓ Correct value: ${expected.value}`);
|
|
} else {
|
|
console.log(` ⚠ Value may differ from expected`);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
console.log(`❌ ${header}: NOT FOUND`);
|
|
allPassed = false;
|
|
}
|
|
}
|
|
|
|
console.log('━'.repeat(60));
|
|
|
|
if (allPassed) {
|
|
console.log('\n✅ SUCCESS: All required security headers are configured!\n');
|
|
console.log('Next steps for manual verification:');
|
|
console.log('1. Start dev server: npm run dev');
|
|
console.log('2. Check headers: curl -I http://localhost:3000');
|
|
console.log('3. Open browser DevTools > Network tab');
|
|
console.log('4. Verify no CSP violations in Console\n');
|
|
process.exit(0);
|
|
} else {
|
|
console.log('\n❌ FAILURE: Some required headers are missing!\n');
|
|
process.exit(1);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error reading configuration:', error.message);
|
|
process.exit(1);
|
|
}
|