Browser Developer Tools for CSP

Browser Developer Tools for CSP

Modern browsers provide powerful built-in tools for CSP debugging. Understanding how to leverage these tools significantly improves debugging efficiency.

Chrome DevTools CSP debugging:

// Chrome Extension for Enhanced CSP Debugging
const CSPDebuggerExtension = {
  init() {
    // Monitor CSP headers
    chrome.webRequest.onHeadersReceived.addListener(
      this.analyzeCSPHeaders,
      { urls: ["<all_urls>"] },
      ["responseHeaders"]
    );
    
    // Inject debugging script
    chrome.tabs.onUpdated.addListener(this.injectDebugger);
  },
  
  analyzeCSPHeaders(details) {
    const cspHeader = details.responseHeaders.find(
      header => header.name.toLowerCase() === 'content-security-policy'
    );
    
    if (cspHeader) {
      const analysis = this.parseAndAnalyzeCSP(cspHeader.value);
      this.displayAnalysis(details.tabId, analysis);
    }
  },
  
  parseAndAnalyzeCSP(policy) {
    const directives = policy.split(';').reduce((acc, directive) => {
      const [name, ...sources] = directive.trim().split(/\s+/);
      if (name) {
        acc[name] = sources;
      }
      return acc;
    }, {});
    
    return {
      directives,
      issues: this.detectCommonIssues(directives),
      security_score: this.calculateSecurityScore(directives)
    };
  },
  
  detectCommonIssues(directives) {
    const issues = [];
    
    if (directives['script-src']?.includes("'unsafe-inline'")) {
      issues.push({
        severity: 'high',
        directive: 'script-src',
        issue: 'Uses unsafe-inline',
        fix: 'Use nonces or hashes instead'
      });
    }
    
    if (directives['script-src']?.includes("'unsafe-eval'")) {
      issues.push({
        severity: 'high',
        directive: 'script-src',
        issue: 'Allows eval()',
        fix: 'Refactor code to avoid eval()'
      });
    }
    
    if (!directives['default-src']) {
      issues.push({
        severity: 'medium',
        directive: 'default-src',
        issue: 'Missing default-src',
        fix: 'Add default-src as fallback'
      });
    }
    
    return issues;
  },
  
  injectDebugger(tabId, changeInfo, tab) {
    if (changeInfo.status === 'complete') {
      chrome.tabs.executeScript(tabId, {
        code: `
          // CSP Violation Monitor
          (function() {
            const violations = [];
            
            document.addEventListener('securitypolicyviolation', (e) => {
              const violation = {
                blockedURI: e.blockedURI,
                violatedDirective: e.violatedDirective,
                effectiveDirective: e.effectiveDirective,
                originalPolicy: e.originalPolicy,
                sourceFile: e.sourceFile,
                lineNumber: e.lineNumber,
                columnNumber: e.columnNumber,
                timestamp: new Date().toISOString()
              };
              
              violations.push(violation);
              console.warn('CSP Violation:', violation);
              
              // Visual indicator
              const indicator = document.createElement('div');
              indicator.style.cssText = \`
                position: fixed;
                top: 10px;
                right: 10px;
                background: #ff4444;
                color: white;
                padding: 10px;
                border-radius: 5px;
                z-index: 99999;
              \`;
              indicator.textContent = \`CSP Violation: \${e.violatedDirective}\`;
              document.body.appendChild(indicator);
              
              setTimeout(() => indicator.remove(), 3000);
            });
            
            window.__CSP_VIOLATIONS__ = violations;
          })();
        `
      });
    }
  }
};