ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
294 lines • 12.6 kB
JavaScript
/**
* NextJSSecurityAnalyzer - Analyzes Next.js security configuration and vulnerabilities
*
* This module handles:
* - Security header analysis and validation
* - Environment variable exposure detection
* - Middleware security analysis
* - CORS and CSP configuration validation
* - Security audit reporting
*/
export class NextJSSecurityAnalyzer {
/**
* Analyze the security configuration of a Next.js application
*/
async analyzeSecurityConfiguration(page) {
try {
const securityData = await page.evaluate(() => {
const debug = window.__NEXTJS_ADVANCED_DEBUG__;
if (!debug?.security) {
return {
security: {
exposedEnvVars: [],
headers: {}
}
};
}
return { security: debug.security };
});
const { security } = securityData;
// Analyze environment variables
const exposed = security.exposedEnvVars || [];
const warnings = [];
if (exposed.length > 0) {
warnings.push(`Found ${exposed.length} potentially exposed server environment variables`);
}
// Check for proper NEXT_PUBLIC_ prefixing
const properlyPrefixed = exposed.filter((envVar) => envVar.startsWith('NEXT_PUBLIC_'));
if (exposed.length > properlyPrefixed.length) {
warnings.push('Some environment variables may be exposed without NEXT_PUBLIC_ prefix');
}
// Analyze security headers
const headers = security.headers || {};
const missingHeaders = [];
if (!headers.csp)
missingHeaders.push('Content-Security-Policy');
if (!headers.xFrameOptions)
missingHeaders.push('X-Frame-Options');
if (!headers.permissionsPolicy)
missingHeaders.push('Permissions-Policy');
if (!headers.hsts)
missingHeaders.push('Strict-Transport-Security');
return {
environmentVariables: {
exposed,
properlyPrefixed,
warnings
},
headers: {
csp: !!headers.csp,
xFrameOptions: headers.xFrameOptions || '',
permissionsPolicy: !!headers.permissionsPolicy,
cors: headers.cors || '',
hsts: !!headers.hsts,
missingHeaders
}
};
}
catch (error) {
console.error('Error analyzing security configuration:', error);
return {
environmentVariables: {
exposed: [],
properlyPrefixed: [],
warnings: ['Failed to analyze environment variables']
},
headers: {
csp: false,
xFrameOptions: '',
permissionsPolicy: false,
cors: '',
hsts: false,
missingHeaders: ['Content-Security-Policy', 'X-Frame-Options', 'Permissions-Policy', 'Strict-Transport-Security']
}
};
}
}
/**
* Analyze middleware security configuration and performance
*/
async analyzeMiddlewareSecurity(page) {
try {
const middlewareData = await page.evaluate(() => {
const debug = window.__NEXTJS_ADVANCED_DEBUG__;
if (!debug?.middleware)
return null;
return {
middlewareFiles: debug.middleware.files || [],
executionPath: debug.middleware.executionPath || [],
rewriteRules: debug.middleware.rewrites || [],
redirects: debug.middleware.redirects || [],
performance: debug.middleware.performance || {
averageExecutionTime: 0,
slowestMiddleware: '',
totalTime: 0
}
};
});
if (!middlewareData)
return null;
// Handle incomplete data by providing defaults
const safeMiddlewareData = {
middlewareFiles: middlewareData.middlewareFiles || [],
executionPath: middlewareData.executionPath || [],
rewriteRules: middlewareData.rewriteRules || [],
redirects: middlewareData.redirects || [],
performance: middlewareData.performance || {
averageExecutionTime: 0,
slowestMiddleware: '',
totalTime: 0
}
};
return {
middlewareFiles: safeMiddlewareData.middlewareFiles.map((file) => ({
path: file.path || '',
size: file.size || 0,
exports: file.exports || []
})),
executionPath: safeMiddlewareData.executionPath,
rewriteRules: safeMiddlewareData.rewriteRules.map((rule) => ({
source: rule.source || '',
destination: rule.destination || '',
condition: rule.condition
})),
redirects: safeMiddlewareData.redirects.map((redirect) => ({
source: redirect.source || '',
destination: redirect.destination || '',
permanent: !!redirect.permanent
})),
performance: {
averageExecutionTime: safeMiddlewareData.performance.averageExecutionTime || 0,
slowestMiddleware: safeMiddlewareData.performance.slowestMiddleware || '',
totalTime: safeMiddlewareData.performance.totalTime || 0
}
};
}
catch (error) {
console.error('Error analyzing middleware security:', error);
return null;
}
}
/**
* Perform comprehensive security audit
*/
auditSecurityConfiguration(securityAnalysis, middlewareAnalysis) {
const issues = [];
const recommendations = [];
const criticalFindings = [];
let score = 100;
// Environment variables audit
if (securityAnalysis.environmentVariables.exposed.length > 0) {
const exposedCount = securityAnalysis.environmentVariables.exposed.length;
const properCount = securityAnalysis.environmentVariables.properlyPrefixed.length;
if (exposedCount > properCount) {
criticalFindings.push('Server environment variables exposed without NEXT_PUBLIC_ prefix');
score -= 30;
}
if (exposedCount > 5) {
issues.push('Large number of environment variables exposed to client');
recommendations.push('Review environment variable exposure and minimize client-side access');
score -= 10;
}
}
// Security headers audit
if (!securityAnalysis.headers.csp) {
criticalFindings.push('Missing Content-Security-Policy header');
recommendations.push('Implement CSP header to prevent XSS attacks');
score -= 25;
}
if (!securityAnalysis.headers.xFrameOptions) {
issues.push('Missing X-Frame-Options header');
recommendations.push('Add X-Frame-Options: DENY to prevent clickjacking');
score -= 15;
}
if (!securityAnalysis.headers.permissionsPolicy) {
issues.push('Missing Permissions-Policy header');
recommendations.push('Implement Permissions-Policy to control browser features');
score -= 10;
}
if (!securityAnalysis.headers.hsts) {
issues.push('Missing HSTS header');
recommendations.push('Enable HSTS for secure transport');
score -= 15;
}
// Middleware security audit
if (middlewareAnalysis) {
if (middlewareAnalysis.performance.averageExecutionTime > 100) {
issues.push('Slow middleware execution detected');
recommendations.push('Optimize middleware performance to reduce latency');
score -= 5;
}
if (middlewareAnalysis.rewriteRules.length > 10) {
issues.push('Large number of rewrite rules');
recommendations.push('Review and optimize rewrite rules for performance');
score -= 5;
}
}
return {
score: Math.max(0, Math.min(100, score)),
issues,
recommendations,
criticalFindings,
environmentAnalysis: securityAnalysis.environmentVariables,
headerAnalysis: securityAnalysis.headers
};
}
/**
* Get specific security improvement suggestions
*/
getSecuritySuggestions(securityAnalysis) {
const suggestions = [];
// CSP suggestions
if (!securityAnalysis.headers.csp) {
suggestions.push("Implement Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'");
}
// Environment variable suggestions - only if there are improperly exposed variables
const improperlyExposed = securityAnalysis.environmentVariables.exposed.length - securityAnalysis.environmentVariables.properlyPrefixed.length;
if (improperlyExposed > 0) {
suggestions.push('Review all exposed environment variables and ensure they use NEXT_PUBLIC_ prefix if client access is needed');
}
// Header suggestions
if (securityAnalysis.headers.missingHeaders.length > 0) {
suggestions.push(`Add missing security headers: ${securityAnalysis.headers.missingHeaders.join(', ')}`);
}
// CORS suggestions
if (securityAnalysis.headers.cors && securityAnalysis.headers.cors.includes('*')) {
suggestions.push('Avoid wildcard CORS configuration; specify exact origins');
}
return suggestions;
}
/**
* Generate comprehensive security analysis report
*/
async generateSecurityReport(page) {
try {
const securityAnalysis = await this.analyzeSecurityConfiguration(page);
const middlewareAnalysis = await this.analyzeMiddlewareSecurity(page);
const audit = this.auditSecurityConfiguration(securityAnalysis, middlewareAnalysis);
const suggestions = this.getSecuritySuggestions(securityAnalysis);
const criticalCount = audit.criticalFindings.length;
const issueCount = audit.issues.length;
const summary = `Security Analysis Summary:
Score: ${audit.score}/100
Critical Issues: ${criticalCount}
Total Issues: ${issueCount}
Environment Variables: ${securityAnalysis.environmentVariables.exposed.length} exposed
Security Headers: ${4 - securityAnalysis.headers.missingHeaders.length}/4 configured`;
return {
summary,
analysis: securityAnalysis,
middleware: middlewareAnalysis,
audit,
suggestions
};
}
catch (error) {
console.error('Error generating security report:', error);
throw error;
}
}
/**
* Validate CORS configuration security
*/
validateCORSConfiguration(corsHeader) {
const issues = [];
const recommendations = [];
let isSecure = true;
if (!corsHeader) {
recommendations.push('Configure CORS headers explicitly for API routes');
return { isSecure: true, issues, recommendations };
}
if (corsHeader.includes('*')) {
issues.push('Wildcard CORS configuration detected');
recommendations.push('Replace wildcard with specific origin domains');
isSecure = false;
}
if (corsHeader.includes('null')) {
issues.push('CORS allows null origin');
recommendations.push('Remove null from allowed origins');
isSecure = false;
}
return { isSecure, issues, recommendations };
}
}
//# sourceMappingURL=nextjs-security-analyzer.js.map