Handling Legacy JavaScript Patterns
Handling Legacy JavaScript Patterns
Legacy applications often use JavaScript patterns that conflict with CSP. Here's how to modernize these patterns:
// Legacy JavaScript Pattern Modernization
class LegacyJSModernizer {
constructor() {
this.patterns = this.definePatternReplacements();
}
definePatternReplacements() {
return {
// Replace eval() usage
evalReplacement: {
pattern: /eval\s*\(\s*([^)]+)\s*\)/g,
replace: (match, code) => {
// For JSON parsing
if (code.includes('{') || code.includes('[')) {
return `JSON.parse(${code})`;
}
// For dynamic property access
if (code.includes('.')) {
return `getPropertyByPath(${code})`;
}
// Flag for manual review
return `/* CSP-REVIEW: eval(${code}) */`;
}
},
// Replace new Function()
functionConstructor: {
pattern: /new\s+Function\s*\(([^)]+)\)/g,
replace: (match, args) => {
console.warn('Function constructor found, needs manual refactoring:', match);
return `/* CSP-TODO: new Function(${args}) */`;
}
},
// Replace setTimeout/setInterval with strings
setTimeoutString: {
pattern: /setTimeout\s*\(\s*["']([^"']+)["']\s*,/g,
replace: (match, code) => {
return `setTimeout(function() { ${code} },`;
}
},
// Replace document.write
documentWrite: {
pattern: /document\.(write|writeln)\s*\(([^)]+)\)/g,
replace: (match, method, content) => {
return `appendToDocument(${content})`;
}
}
};
}
modernizeCode(code) {
let modernized = code;
Object.values(this.patterns).forEach(({ pattern, replace }) => {
modernized = modernized.replace(pattern, replace);
});
// Add helper functions
const helpers = `
// Helper functions for CSP compliance
function getPropertyByPath(obj, path) {
return path.split('.').reduce((current, prop) => current?.[prop], obj);
}
function appendToDocument(content) {
const div = document.createElement('div');
div.innerHTML = content;
document.body.appendChild(div);
}
function safeEval(expression) {
console.warn('safeEval called, consider refactoring:', expression);
// Implement safe evaluation logic
return null;
}
`;
return helpers + '\n' + modernized;
}
// Specific pattern migrations
migrateAjaxPatterns() {
return {
// Old jQuery AJAX with eval
old: `
$.ajax({
url: '/api/data',
dataType: 'script',
success: function(data) {
eval(data);
}
});
`,
// Modern CSP-compliant version
new: `
$.ajax({
url: '/api/data',
dataType: 'json',
success: function(data) {
processData(data);
}
});
function processData(data) {
// Process JSON data instead of executing scripts
if (data.action) {
handleAction(data.action, data.parameters);
}
}
`
};
}
}