Policy Optimization and Performance
Policy Optimization and Performance
CSP can impact performance if not optimized properly. Implementing performance-conscious CSP ensures security without degrading user experience:
// CSP Performance Optimizer
class CSPPerformanceOptimizer {
constructor() {
this.metrics = new Map();
this.optimizations = [];
}
analyzePerformanceImpact(policy) {
const analysis = {
policySize: this.calculatePolicySize(policy),
parseComplexity: this.assessParseComplexity(policy),
resourceBlocking: this.evaluateResourceBlocking(policy),
recommendations: []
};
// Policy size optimization
if (analysis.policySize > 1024) {
analysis.recommendations.push({
issue: 'Large policy size',
impact: 'Increased header overhead',
solution: 'Consider using CSP meta tags for static policies'
});
}
// Complexity optimization
if (analysis.parseComplexity > 50) {
analysis.recommendations.push({
issue: 'Complex policy structure',
impact: 'Slower policy parsing',
solution: 'Simplify directives and consolidate sources'
});
}
return analysis;
}
optimizePolicy(policy) {
const optimized = {};
Object.entries(policy).forEach(([directive, sources]) => {
// Remove duplicates
const uniqueSources = [...new Set(sources)];
// Consolidate domains
const consolidated = this.consolidateDomains(uniqueSources);
// Sort for consistency
optimized[directive] = consolidated.sort();
});
return optimized;
}
consolidateDomains(sources) {
const domains = new Map();
sources.forEach(source => {
if (source.startsWith('https://') || source.startsWith('http://')) {
const url = new URL(source);
const domain = url.hostname;
if (!domains.has(domain)) {
domains.set(domain, new Set());
}
domains.get(domain).add(url.pathname);
}
});
// Consolidate subdomains where possible
const consolidated = [];
domains.forEach((paths, domain) => {
if (paths.size === 1 && paths.has('/')) {
consolidated.push(`https://${domain}`);
} else {
paths.forEach(path => {
consolidated.push(`https://${domain}${path}`);
});
}
});
return consolidated;
}
implementCaching() {
return {
clientSide: `
// Cache CSP nonce for session
class CSPNonceCache {
constructor() {
this.nonce = this.getOrCreateNonce();
}
getOrCreateNonce() {
const cached = sessionStorage.getItem('csp-nonce');
if (cached && this.isValid(cached)) {
return cached;
}
const newNonce = this.extractNonce();
sessionStorage.setItem('csp-nonce', newNonce);
return newNonce;
}
extractNonce() {
const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
if (meta) {
const match = meta.content.match(/nonce-([A-Za-z0-9+/=]+)/);
return match ? match[1] : null;
}
return null;
}
}
`,
serverSide: `
// Server-side CSP caching
const CSPCache = require('node-cache');
const cspCache = new CSPCache({ stdTTL: 600 }); // 10 minute cache
function getCachedPolicy(userContext) {
const key = generateCacheKey(userContext);
let policy = cspCache.get(key);
if (!policy) {
policy = generatePolicy(userContext);
cspCache.set(key, policy);
}
return policy;
}
`
};
}
}