Assessing Legacy Application Challenges
Assessing Legacy Application Challenges
Legacy applications often contain years or decades of accumulated code that predates modern security practices. Understanding these specific challenges is crucial for planning a successful CSP migration that doesn't break critical functionality.
Comprehensive legacy assessment framework:
// Legacy Application CSP Assessment Tool
class LegacyCSPAssessment {
constructor(applicationUrl) {
this.url = applicationUrl;
this.findings = {
inlineScripts: [],
inlineStyles: [],
eventHandlers: [],
dynamicContent: [],
thirdPartyDependencies: [],
evalUsage: [],
deprecatedPatterns: []
};
}
async performComprehensiveAudit() {
console.log('Starting legacy application CSP assessment...');
const audit = {
codeAnalysis: await this.analyzeCodebase(),
runtimeAnalysis: await this.analyzeRuntime(),
dependencyAnalysis: await this.analyzeDependencies(),
securityRiskAssessment: await this.assessSecurityRisks(),
migrationComplexity: await this.calculateMigrationComplexity()
};
return this.generateAssessmentReport(audit);
}
async analyzeCodebase() {
const analysis = {
totalFiles: 0,
problematicPatterns: {},
refactoringNeeded: []
};
// Scan for inline event handlers
const eventHandlerPattern = /on(click|load|mouseover|change|submit|keyup|keydown|focus|blur)\s*=/gi;
// Scan for eval usage
const evalPattern = /eval\s*\(|new\s+Function\s*\(|setTimeout\s*\(['"]/gi;
// Scan for document.write
const documentWritePattern = /document\.(write|writeln)\s*\(/gi;
// Scan for inline styles
const inlineStylePattern = /style\s*=\s*["'][^"']+["']/gi;
return {
inlineHandlers: {
count: 0,
examples: [],
estimatedEffort: 'hours'
},
evalUsage: {
count: 0,
contexts: [],
alternatives: []
},
dynamicContent: {
documentWrite: 0,
innerHTML: 0,
recommendations: []
}
};
}
async analyzeRuntime() {
// Runtime analysis using headless browser
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Intercept and analyze resources
const resources = {
scripts: new Map(),
styles: new Map(),
connections: new Set()
};
page.on('request', request => {
const type = request.resourceType();
const url = request.url();
if (type === 'script') {
resources.scripts.set(url, {
type: 'external',
origin: new URL(url).origin
});
} else if (type === 'stylesheet') {
resources.styles.set(url, {
type: 'external',
origin: new URL(url).origin
});
} else if (type === 'xhr' || type === 'fetch') {
resources.connections.add(new URL(url).origin);
}
});
// Navigate and analyze
await page.goto(this.url, { waitUntil: 'networkidle2' });
// Analyze inline content
const inlineAnalysis = await page.evaluate(() => {
const results = {
inlineScripts: [],
inlineStyles: [],
eventHandlers: []
};
// Find inline scripts
document.querySelectorAll('script:not([src])').forEach(script => {
results.inlineScripts.push({
content: script.textContent.substring(0, 100) + '...',
length: script.textContent.length,
location: script.closest('[id]')?.id || 'unknown'
});
});
// Find inline styles
document.querySelectorAll('[style]').forEach(element => {
results.inlineStyles.push({
tag: element.tagName,
style: element.getAttribute('style'),
id: element.id || element.className
});
});
// Find inline event handlers
const eventAttributes = ['onclick', 'onload', 'onchange', 'onsubmit'];
eventAttributes.forEach(attr => {
document.querySelectorAll(`[${attr}]`).forEach(element => {
results.eventHandlers.push({
event: attr,
handler: element.getAttribute(attr).substring(0, 50) + '...',
element: element.tagName,
id: element.id
});
});
});
return results;
});
await browser.close();
return {
resources,
inlineContent: inlineAnalysis,
recommendations: this.generateRuntimeRecommendations(resources, inlineAnalysis)
};
}
generateAssessmentReport(audit) {
const report = {
summary: {
applicationUrl: this.url,
assessmentDate: new Date().toISOString(),
overallReadiness: this.calculateReadinessScore(audit),
estimatedEffort: this.estimateEffort(audit)
},
findings: {
criticalIssues: this.identifyCriticalIssues(audit),
moderateIssues: this.identifyModerateIssues(audit),
minorIssues: this.identifyMinorIssues(audit)
},
migrationPlan: this.generateMigrationPlan(audit),
recommendations: {
immediate: [
'Implement CSP in report-only mode',
'Set up violation monitoring',
'Create refactoring backlog'
],
shortTerm: [
'Refactor inline event handlers',
'Move inline scripts to external files',
'Implement nonce generation system'
],
longTerm: [
'Modernize JavaScript patterns',
'Implement build-time CSP generation',
'Automate CSP testing'
]
}
};
return report;
}
}