前端安全防护深度实践:从XSS到CSRF的完整安全解决方案

发布于:2025-09-02 ⋅ 阅读:(16) ⋅ 点赞:(0)

在数字化时代,前端安全已成为Web应用的生命线。本文将深入探讨现代前端安全防护体系,从XSS、CSRF等经典攻击到现代安全威胁,提供完整的防护解决方案和最佳实践。

1. 前端安全概述

1.1 安全威胁分析

前端安全面临的主要威胁包括:

  • XSS攻击:跨站脚本攻击,注入恶意脚本
  • CSRF攻击:跨站请求伪造,利用用户身份执行恶意操作
  • 点击劫持:通过透明iframe诱导用户点击
  • 数据泄露:敏感信息暴露和传输安全
  • 依赖安全:第三方库和组件的安全漏洞
  • 内容安全:恶意内容注入和篡改

1.2 安全防护架构

// 前端安全管理器
class FrontendSecurityManager {
  constructor(config = {}) {
    this.config = {
      enableXSSProtection: true,
      enableCSRFProtection: true,
      enableClickjackingProtection: true,
      enableContentSecurityPolicy: true,
      enableInputValidation: true,
      enableSecureStorage: true,
      enableSecureCommunication: true,
      enableDependencyScanning: true,
      ...config
    };
    
    this.protectionModules = new Map();
    this.securityEvents = [];
    this.threatDetectors = new Map();
    this.securityPolicies = new Map();
    
    this.init();
  }
  
  // 初始化安全模块
  init() {
    if (this.config.enableXSSProtection) {
      this.protectionModules.set('xss', new XSSProtection());
    }
    
    if (this.config.enableCSRFProtection) {
      this.protectionModules.set('csrf', new CSRFProtection());
    }
    
    if (this.config.enableClickjackingProtection) {
      this.protectionModules.set('clickjacking', new ClickjackingProtection());
    }
    
    if (this.config.enableContentSecurityPolicy) {
      this.protectionModules.set('csp', new ContentSecurityPolicy());
    }
    
    if (this.config.enableInputValidation) {
      this.protectionModules.set('input', new InputValidation());
    }
    
    if (this.config.enableSecureStorage) {
      this.protectionModules.set('storage', new SecureStorage());
    }
    
    if (this.config.enableSecureCommunication) {
      this.protectionModules.set('communication', new SecureCommunication());
    }
    
    if (this.config.enableDependencyScanning) {
      this.protectionModules.set('dependency', new DependencyScanner());
    }
    
    this.setupGlobalProtection();
    this.startThreatMonitoring();
  }
  
  // 设置全局保护
  setupGlobalProtection() {
    // 设置全局错误处理
    window.addEventListener('error', (event) => {
      this.handleSecurityEvent({
        type: 'error',
        message: event.message,
        source: event.filename,
        line: event.lineno,
        column: event.colno,
        timestamp: Date.now()
      });
    });
    
    // 设置CSP违规处理
    document.addEventListener('securitypolicyviolation', (event) => {
      this.handleSecurityEvent({
        type: 'csp_violation',
        violatedDirective: event.violatedDirective,
        blockedURI: event.blockedURI,
        documentURI: event.documentURI,
        timestamp: Date.now()
      });
    });
    
    // 监控DOM变化
    if (typeof MutationObserver !== 'undefined') {
      const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          this.scanDOMChanges(mutation);
        });
      });
      
      observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['src', 'href', 'onclick', 'onload']
      });
    }
  }
  
  // 启动威胁监控
  startThreatMonitoring() {
    // 定期扫描威胁
    setInterval(() => {
      this.performSecurityScan();
    }, 30000); // 每30秒扫描一次
    
    // 监控网络请求
    this.interceptNetworkRequests();
    
    // 监控用户行为
    this.monitorUserBehavior();
  }
  
  // 处理安全事件
  handleSecurityEvent(event) {
    this.securityEvents.push(event);
    
    // 触发相应的保护模块
    this.protectionModules.forEach((module, type) => {
      if (module.canHandle && module.canHandle(event)) {
        module.handle(event);
      }
    });
    
    // 发送安全报告
    this.reportSecurityEvent(event);
    
    // 检查是否需要紧急响应
    if (this.isHighRiskEvent(event)) {
      this.triggerEmergencyResponse(event);
    }
  }
  
  // 扫描DOM变化
  scanDOMChanges(mutation) {
    const xssProtection = this.protectionModules.get('xss');
    if (xssProtection) {
      xssProtection.scanMutation(mutation);
    }
  }
  
  // 执行安全扫描
  performSecurityScan() {
    const scanResults = {};
    
    this.protectionModules.forEach((module, type) => {
      if (module.scan) {
        scanResults[type] = module.scan();
      }
    });
    
    return scanResults;
  }
  
  // 拦截网络请求
  interceptNetworkRequests() {
    const originalFetch = window.fetch;
    const originalXHR = window.XMLHttpRequest;
    
    // 拦截fetch请求
    window.fetch = async (...args) => {
      const [url, options] = args;
      
      // CSRF保护
      const csrfProtection = this.protectionModules.get('csrf');
      if (csrfProtection) {
        args[1] = csrfProtection.protectRequest(url, options);
      }
      
      // 安全通信保护
      const secureComm = this.protectionModules.get('communication');
      if (secureComm) {
        args[1] = secureComm.protectRequest(url, args[1]);
      }
      
      try {
        const response = await originalFetch.apply(this, args);
        
        // 检查响应安全性
        this.validateResponse(response);
        
        return response;
      } catch (error) {
        this.handleSecurityEvent({
          type: 'network_error',
          url,
          error: error.message,
          timestamp: Date.now()
        });
        throw error;
      }
    };
    
    // 拦截XMLHttpRequest
    window.XMLHttpRequest = function() {
      const xhr = new originalXHR();
      const originalOpen = xhr.open;
      const originalSend = xhr.send;
      
      xhr.open = function(method, url, ...args) {
        this._url = url;
        this._method = method;
        return originalOpen.apply(this, [method, url, ...args]);
      };
      
      xhr.send = function(data) {
        // CSRF保护
        const csrfProtection = this.protectionModules.get('csrf');
        if (csrfProtection) {
          csrfProtection.protectXHR(this);
        }
        
        return originalSend.apply(this, [data]);
      }.bind(this);
      
      return xhr;
    }.bind(this);
  }
  
  // 监控用户行为
  monitorUserBehavior() {
    let clickCount = 0;
    let lastClickTime = 0;
    
    document.addEventListener('click', (event) => {
      const currentTime = Date.now();
      
      // 检测异常点击行为
      if (currentTime - lastClickTime < 100) {
        clickCount++;
        if (clickCount > 10) {
          this.handleSecurityEvent({
            type: 'suspicious_clicking',
            element: event.target.tagName,
            timestamp: currentTime
          });
          clickCount = 0;
        }
      } else {
        clickCount = 0;
      }
      
      lastClickTime = currentTime;
      
      // 检查点击劫持
      const clickjackingProtection = this.protectionModules.get('clickjacking');
      if (clickjackingProtection) {
        clickjackingProtection.validateClick(event);
      }
    });
  }
  
  // 验证响应安全性
  validateResponse(response) {
    // 检查响应头
    const securityHeaders = [
      'x-frame-options',
      'x-content-type-options',
      'x-xss-protection',
      'strict-transport-security',
      'content-security-policy'
    ];
    
    const missingHeaders = securityHeaders.filter(header => 
      !response.headers.has(header)
    );
    
    if (missingHeaders.length > 0) {
      this.handleSecurityEvent({
        type: 'missing_security_headers',
        headers: missingHeaders,
        url: response.url,
        timestamp: Date.now()
      });
    }
  }
  
  // 判断是否为高风险事件
  isHighRiskEvent(event) {
    const highRiskTypes = [
      'xss_detected',
      'csrf_attack',
      'clickjacking_attempt',
      'data_exfiltration',
      'malicious_script'
    ];
    
    return highRiskTypes.includes(event.type);
  }
  
  // 触发紧急响应
  triggerEmergencyResponse(event) {
    console.warn('🚨 Security Alert:', event);
    
    // 可以在这里实现更多紧急响应措施
    // 例如:禁用某些功能、清除敏感数据、通知服务器等
    
    if (event.type === 'xss_detected') {
      // 清理可能的XSS内容
      this.protectionModules.get('xss')?.emergencyCleanup();
    }
    
    if (event.type === 'data_exfiltration') {
      // 阻止数据传输
      this.blockDataTransmission();
    }
  }
  
  // 阻止数据传输
  blockDataTransmission() {
    // 临时禁用网络请求
    const originalFetch = window.fetch;
    window.fetch = () => Promise.reject(new Error('Data transmission blocked for security'));
    
    // 5分钟后恢复
    setTimeout(() => {
      window.fetch = originalFetch;
    }, 5 * 60 * 1000);
  }
  
  // 报告安全事件
  reportSecurityEvent(event) {
    // 发送到安全监控服务
    if (typeof navigator.sendBeacon === 'function') {
      const data = JSON.stringify({
        event,
        userAgent: navigator.userAgent,
        url: window.location.href,
        timestamp: Date.now()
      });
      
      navigator.sendBeacon('/api/security/report', data);
    }
  }
  
  // 获取安全状态
  getSecurityStatus() {
    const status = {
      protectionModules: {},
      recentEvents: this.securityEvents.slice(-10),
      threatLevel: this.calculateThreatLevel(),
      lastScan: this.lastScanTime
    };
    
    this.protectionModules.forEach((module, type) => {
      status.protectionModules[type] = {
        enabled: true,
        status: module.getStatus ? module.getStatus() : 'active',
        lastUpdate: module.lastUpdate || Date.now()
      };
    });
    
    return status;
  }
  
  // 计算威胁等级
  calculateThreatLevel() {
    const recentEvents = this.securityEvents.filter(
      event => Date.now() - event.timestamp < 3600000 // 最近1小时
    );
    
    const highRiskEvents = recentEvents.filter(event => 
      this.isHighRiskEvent(event)
    ).length;
    
    if (highRiskEvents > 5) return 'critical';
    if (highRiskEvents > 2) return 'high';
    if (recentEvents.length > 10) return 'medium';
    return 'low';
  }
  
  // 更新安全配置
  updateConfig(newConfig) {
    this.config = { ...this.config, ...newConfig };
    
    // 重新初始化受影响的模块
    Object.keys(newConfig).forEach(key => {
      if (key.startsWith('enable')) {
        const moduleName = key.replace('enable', '').replace('Protection', '').toLowerCase();
        
        if (newConfig[key] && !this.protectionModules.has(moduleName)) {
          // 启用模块
          this.enableProtectionModule(moduleName);
        } else if (!newConfig[key] && this.protectionModules.has(moduleName)) {
          // 禁用模块
          this.disableProtectionModule(moduleName);
        }
      }
    });
  }
  
  // 启用保护模块
  enableProtectionModule(moduleName) {
    switch (moduleName) {
      case 'xss':
        this.protectionModules.set('xss', new XSSProtection());
        break;
      case 'csrf':
        this.protectionModules.set('csrf', new CSRFProtection());
        break;
      // ... 其他模块
    }
  }
  
  // 禁用保护模块
  disableProtectionModule(moduleName) {
    const module = this.protectionModules.get(moduleName);
    if (module && module.cleanup) {
      module.cleanup();
    }
    this.protectionModules.delete(moduleName);
  }
}

2. XSS防护深度实践

2.1 XSS攻击类型与检测

// XSS保护模块
class XSSProtection {
  constructor(config = {}) {
    this.config = {
      enableReflectedXSSProtection: true,
      enableStoredXSSProtection: true,
      enableDOMXSSProtection: true,
      enableContentSanitization: true,
      enableInputValidation: true,
      strictMode: false,
      ...config
    };
    
    this.xssPatterns = this.initializeXSSPatterns();
    this.sanitizer = new DOMPurify();
    this.detectedThreats = [];
    this.whitelist = new Set();
    this.blacklist = new Set();
    
    this.init();
  }
  
  // 初始化XSS检测模式
  initializeXSSPatterns() {
    return {
      // 脚本标签模式
      scriptTags: [
        /<script[^>]*>.*?<\/script>/gi,
        /<script[^>]*>/gi,
        /javascript:/gi,
        /vbscript:/gi
      ],
      
      // 事件处理器模式
      eventHandlers: [
        /on\w+\s*=/gi,
        /onclick/gi,
        /onload/gi,
        /onerror/gi,
        /onmouseover/gi
      ],
      
      // 数据URI模式
      dataUris: [
        /data:text\/html/gi,
        /data:application\/javascript/gi,
        /data:text\/javascript/gi
      ],
      
      // 表达式模式
      expressions: [
        /expression\s*\(/gi,
        /eval\s*\(/gi,
        /setTimeout\s*\(/gi,
        /setInterval\s*\(/gi
      ],
      
      // 编码绕过模式
      encodingBypass: [
        /&#x[0-9a-f]+;/gi,
        /&#[0-9]+;/gi,
        /%[0-9a-f]{2}/gi,
        /\\u[0-9a-f]{4}/gi
      ]
    };
  }
  
  // 初始化保护
  init() {
    this.setupInputProtection();
    this.setupOutputProtection();
    this.setupDOMProtection();
    this.setupCSPIntegration();
  }
  
  // 设置输入保护
  setupInputProtection() {
    // 监控表单输入
    document.addEventListener('input', (event) => {
      if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
        this.validateInput(event.target);
      }
    });
    
    // 监控粘贴事件
    document.addEventListener('paste', (event) => {
      const clipboardData = event.clipboardData || window.clipboardData;
      const pastedData = clipboardData.getData('text');
      
      if (this.detectXSS(pastedData)) {
        event.preventDefault();
        this.handleXSSDetection({
          type: 'paste_xss',
          content: pastedData,
          element: event.target
        });
      }
    });
  }
  
  // 设置输出保护
  setupOutputProtection() {
    // 拦截innerHTML设置
    const originalInnerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
    
    Object.defineProperty(Element.prototype, 'innerHTML', {
      set: function(value) {
        const sanitizedValue = this.sanitizeContent(value);
        return originalInnerHTML.set.call(this, sanitizedValue);
      }.bind(this),
      get: originalInnerHTML.get
    });
    
    // 拦截outerHTML设置
    const originalOuterHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'outerHTML');
    
    Object.defineProperty(Element.prototype, 'outerHTML', {
      set: function(value) {
        const sanitizedValue = this.sanitizeContent(value);
        return originalOuterHTML.set.call(this, sanitizedValue);
      }.bind(this),
      get: originalOuterHTML.get
    });
  }
  
  // 设置DOM保护
  setupDOMProtection() {
    // 监控动态脚本创建
    const originalCreateElement = document.createElement;
    
    document.createElement = function(tagName) {
      const element = originalCreateElement.call(document, tagName);
      
      if (tagName.toLowerCase() === 'script') {
        this.validateScriptElement(element);
      }
      
      return element;
    }.bind(this);
    
    // 监控属性设置
    this.setupAttributeProtection();
  }
  
  // 设置属性保护
  setupAttributeProtection() {
    const dangerousAttributes = ['src', 'href', 'action', 'formaction'];
    
    dangerousAttributes.forEach(attr => {
      this.interceptAttribute(attr);
    });
  }
  
  // 拦截属性设置
  interceptAttribute(attributeName) {
    const originalSetAttribute = Element.prototype.setAttribute;
    
    Element.prototype.setAttribute = function(name, value) {
      if (name.toLowerCase() === attributeName.toLowerCase()) {
        value = this.sanitizeAttributeValue(name, value);
      }
      
      return originalSetAttribute.call(this, name, value);
    }.bind(this);
  }
  
  // 验证输入
  validateInput(element) {
    const value = element.value;
    
    if (this.detectXSS(value)) {
      this.handleXSSDetection({
        type: 'input_xss',
        content: value,
        element: element
      });
      
      // 清理输入
      element.value = this.sanitizeContent(value);
    }
  }
  
  // 检测XSS
  detectXSS(content) {
    if (!content || typeof content !== 'string') {
      return false;
    }
    
    // 检查黑名单
    if (this.blacklist.has(content)) {
      return true;
    }
    
    // 检查白名单
    if (this.whitelist.has(content)) {
      return false;
    }
    
    // 模式匹配检测
    for (const [category, patterns] of Object.entries(this.xssPatterns)) {
      for (const pattern of patterns) {
        if (pattern.test(content)) {
          return true;
        }
      }
    }
    
    // 启发式检测
    return this.heuristicDetection(content);
  }
  
  // 启发式检测
  heuristicDetection(content) {
    const suspiciousIndicators = [
      // 多个连续的特殊字符
      /[<>"'&]{3,}/,
      // 编码后的脚本标签
      /%3Cscript/i,
      // Base64编码的可疑内容
      /data:.*base64.*script/i,
      // 多层编码
      /%25[0-9a-f]{2}/i,
      // 异常的URL协议
      /^(data|javascript|vbscript):/i
    ];
    
    return suspiciousIndicators.some(pattern => pattern.test(content));
  }
  
  // 内容清理
  sanitizeContent(content) {
    if (!content || typeof content !== 'string') {
      return content;
    }
    
    // 使用DOMPurify清理
    if (this.sanitizer && this.sanitizer.sanitize) {
      return this.sanitizer.sanitize(content, {
        ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'p', 'br', 'span'],
        ALLOWED_ATTR: ['class', 'id'],
        FORBID_SCRIPT: true,
        FORBID_TAGS: ['script', 'object', 'embed', 'link', 'style'],
        FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover']
      });
    }
    
    // 备用清理方法
    return this.basicSanitize(content);
  }
  
  // 基础清理
  basicSanitize(content) {
    return content
      .replace(/<script[^>]*>.*?<\/script>/gi, '')
      .replace(/<script[^>]*>/gi, '')
      .replace(/javascript:/gi, '')
      .replace(/on\w+\s*=/gi, '')
      .replace(/expression\s*\(/gi, '')
      .replace(/eval\s*\(/gi, '');
  }
  
  // 清理属性值
  sanitizeAttributeValue(attributeName, value) {
    if (!value || typeof value !== 'string') {
      return value;
    }
    
    // URL属性特殊处理
    if (['src', 'href', 'action', 'formaction'].includes(attributeName.toLowerCase())) {
      return this.sanitizeURL(value);
    }
    
    return this.sanitizeContent(value);
  }
  
  // URL清理
  sanitizeURL(url) {
    // 检查协议
    const dangerousProtocols = ['javascript:', 'vbscript:', 'data:text/html'];
    
    for (const protocol of dangerousProtocols) {
      if (url.toLowerCase().startsWith(protocol)) {
        return '#';
      }
    }
    
    // 检查编码绕过
    const decodedUrl = decodeURIComponent(url);
    if (this.detectXSS(decodedUrl)) {
      return '#';
    }
    
    return url;
  }
  
  // 验证脚本元素
  validateScriptElement(scriptElement) {
    // 监控src属性设置
    Object.defineProperty(scriptElement, 'src', {
      set: function(value) {
        if (this.isAllowedScript(value)) {
          scriptElement._src = value;
        } else {
          this.handleXSSDetection({
            type: 'malicious_script',
            src: value,
            element: scriptElement
          });
        }
      }.bind(this),
      get: function() {
        return scriptElement._src;
      }
    });
  }
  
  // 检查是否为允许的脚本
  isAllowedScript(src) {
    // 检查白名单域名
    const allowedDomains = [
      'cdn.jsdelivr.net',
      'unpkg.com',
      'cdnjs.cloudflare.com'
    ];
    
    try {
      const url = new URL(src, window.location.origin);
      return allowedDomains.some(domain => url.hostname.endsWith(domain));
    } catch {
      return false;
    }
  }
  
  // 处理XSS检测
  handleXSSDetection(threat) {
    this.detectedThreats.push({
      ...threat,
      timestamp: Date.now(),
      userAgent: navigator.userAgent,
      url: window.location.href
    });
    
    // 触发安全事件
    const event = new CustomEvent('xss-detected', {
      detail: threat
    });
    document.dispatchEvent(event);
    
    // 记录到控制台
    console.warn('🛡️ XSS Threat Detected:', threat);
    
    // 严格模式下阻止执行
    if (this.config.strictMode) {
      throw new Error('XSS threat detected and blocked');
    }
  }
  
  // 扫描DOM变化
  scanMutation(mutation) {
    if (mutation.type === 'childList') {
      mutation.addedNodes.forEach(node => {
        if (node.nodeType === Node.ELEMENT_NODE) {
          this.scanElement(node);
        }
      });
    }
    
    if (mutation.type === 'attributes') {
      this.scanElementAttributes(mutation.target);
    }
  }
  
  // 扫描元素
  scanElement(element) {
    // 检查标签名
    if (element.tagName === 'SCRIPT') {
      this.validateScriptElement(element);
    }
    
    // 检查属性
    this.scanElementAttributes(element);
    
    // 递归检查子元素
    element.querySelectorAll('*').forEach(child => {
      this.scanElementAttributes(child);
    });
  }
  
  // 扫描元素属性
  scanElementAttributes(element) {
    const attributes = element.attributes;
    
    for (let i = 0; i < attributes.length; i++) {
      const attr = attributes[i];
      
      // 检查事件处理器
      if (attr.name.startsWith('on')) {
        this.handleXSSDetection({
          type: 'event_handler_xss',
          attribute: attr.name,
          value: attr.value,
          element: element
        });
        
        element.removeAttribute(attr.name);
      }
      
      // 检查危险属性值
      if (this.detectXSS(attr.value)) {
        this.handleXSSDetection({
          type: 'attribute_xss',
          attribute: attr.name,
          value: attr.value,
          element: element
        });
        
        element.setAttribute(attr.name, this.sanitizeAttributeValue(attr.name, attr.value));
      }
    }
  }
  
  // 紧急清理
  emergencyCleanup() {
    // 移除所有脚本标签
    document.querySelectorAll('script').forEach(script => {
      if (!this.isAllowedScript(script.src)) {
        script.remove();
      }
    });
    
    // 移除所有事件处理器
    document.querySelectorAll('*').forEach(element => {
      const attributes = [...element.attributes];
      attributes.forEach(attr => {
        if (attr.name.startsWith('on')) {
          element.removeAttribute(attr.name);
        }
      });
    });
    
    console.log('🧹 Emergency XSS cleanup completed');
  }
  
  // 获取状态
  getStatus() {
    return {
      threatsDetected: this.detectedThreats.length,
      lastThreat: this.detectedThreats[this.detectedThreats.length - 1],
      config: this.config
    };
  }
  
  // 添加到白名单
  addToWhitelist(content) {
    this.whitelist.add(content);
  }
  
  // 添加到黑名单
  addToBlacklist(content) {
    this.blacklist.add(content);
  }
  
  // 清理
  cleanup() {
    this.detectedThreats = [];
    this.whitelist.clear();
    this.blacklist.clear();
  }
}

3. CSRF防护深度实践

3.1 CSRF攻击检测与防护

// CSRF保护模块
class CSRFProtection {
  constructor(config = {}) {
    this.config = {
      tokenName: '_csrf_token',
      headerName: 'X-CSRF-Token',
      cookieName: 'csrf_token',
      tokenLength: 32,
      enableSameSiteCookies: true,
      enableOriginValidation: true,
      enableReferrerValidation: true,
      enableDoubleSubmitCookies: true,
      trustedOrigins: [],
      ...config
    };
    
    this.tokens = new Map();
    this.sessionToken = null;
    this.detectedAttacks = [];
    
    this.init();
  }
  
  // 初始化CSRF保护
  init() {
    this.generateSessionToken();
    this.setupTokenValidation();
    this.setupOriginValidation();
    this.setupSameSiteCookies();
    this.interceptFormSubmissions();
  }
  
  // 生成会话令牌
  generateSessionToken() {
    this.sessionToken = this.generateToken();
    
    // 设置到meta标签
    let metaTag = document.querySelector('meta[name="csrf-token"]');
    if (!metaTag) {
      metaTag = document.createElement('meta');
      metaTag.name = 'csrf-token';
      document.head.appendChild(metaTag);
    }
    metaTag.content = this.sessionToken;
    
    // 设置到cookie(双重提交模式)
    if (this.config.enableDoubleSubmitCookies) {
      this.setCookie(this.config.cookieName, this.sessionToken, {
        secure: location.protocol === 'https:',
        sameSite: 'Strict',
        httpOnly: false // 需要JavaScript访问
      });
    }
  }
  
  // 生成随机令牌
  generateToken() {
    const array = new Uint8Array(this.config.tokenLength);
    crypto.getRandomValues(array);
    return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
  }
  
  // 设置Cookie
  setCookie(name, value, options = {}) {
    let cookieString = `${name}=${value}`;
    
    if (options.expires) {
      cookieString += `; expires=${options.expires.toUTCString()}`;
    }
    
    if (options.maxAge) {
      cookieString += `; max-age=${options.maxAge}`;
    }
    
    if (options.domain) {
      cookieString += `; domain=${options.domain}`;
    }
    
    if (options.path) {
      cookieString += `; path=${options.path}`;
    }
    
    if (options.secure) {
      cookieString += '; secure';
    }
    
    if (options.httpOnly) {
      cookieString += '; httponly';
    }
    
    if (options.sameSite) {
      cookieString += `; samesite=${options.sameSite}`;
    }
    
    document.cookie = cookieString;
  }
  
  // 获取Cookie值
  getCookie(name) {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) {
      return parts.pop().split(';').shift();
    }
    return null;
  }
  
  // 设置令牌验证
  setupTokenValidation() {
    // 为所有表单添加CSRF令牌
    document.addEventListener('DOMContentLoaded', () => {
      this.addTokensToForms();
    });
    
    // 监控新添加的表单
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
          if (node.nodeType === Node.ELEMENT_NODE) {
            if (node.tagName === 'FORM') {
              this.addTokenToForm(node);
            } else {
              const forms = node.querySelectorAll('form');
              forms.forEach(form => this.addTokenToForm(form));
            }
          }
        });
      });
    });
    
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
  
  // 为所有表单添加令牌
  addTokensToForms() {
    const forms = document.querySelectorAll('form');
    forms.forEach(form => this.addTokenToForm(form));
  }
  
  // 为单个表单添加令牌
  addTokenToForm(form) {
    // 检查是否已经有CSRF令牌
    let tokenInput = form.querySelector(`input[name="${this.config.tokenName}"]`);
    
    if (!tokenInput) {
      tokenInput = document.createElement('input');
      tokenInput.type = 'hidden';
      tokenInput.name = this.config.tokenName;
      form.appendChild(tokenInput);
    }
    
    tokenInput.value = this.sessionToken;
  }
  
  // 设置来源验证
  setupOriginValidation() {
    if (!this.config.enableOriginValidation) return;
    
    // 添加受信任的来源
    this.config.trustedOrigins.push(window.location.origin);
  }
  
  // 设置SameSite Cookie
  setupSameSiteCookies() {
    if (!this.config.enableSameSiteCookies) return;
    
    // 检查现有cookie的SameSite设置
    const cookies = document.cookie.split(';');
    cookies.forEach(cookie => {
      const [name] = cookie.trim().split('=');
      if (!cookie.includes('SameSite')) {
        console.warn(`Cookie ${name} missing SameSite attribute`);
      }
    });
  }
  
  // 拦截表单提交
  interceptFormSubmissions() {
    document.addEventListener('submit', (event) => {
      const form = event.target;
      
      if (form.tagName === 'FORM') {
        if (!this.validateFormSubmission(form)) {
          event.preventDefault();
          this.handleCSRFAttack({
            type: 'form_submission',
            form: form,
            action: form.action,
            method: form.method
          });
        }
      }
    });
  }
  
  // 验证表单提交
  validateFormSubmission(form) {
    // 只验证POST、PUT、DELETE等修改性请求
    const method = form.method.toLowerCase();
    if (['get', 'head', 'options'].includes(method)) {
      return true;
    }
    
    // 检查CSRF令牌
    const tokenInput = form.querySelector(`input[name="${this.config.tokenName}"]`);
    if (!tokenInput || tokenInput.value !== this.sessionToken) {
      return false;
    }
    
    // 验证来源
    if (this.config.enableOriginValidation) {
      if (!this.validateOrigin()) {
        return false;
      }
    }
    
    // 验证Referrer
    if (this.config.enableReferrerValidation) {
      if (!this.validateReferrer()) {
        return false;
      }
    }
    
    return true;
  }
  
  // 保护请求
  protectRequest(url, options = {}) {
    const method = (options.method || 'GET').toLowerCase();
    
    // 只保护修改性请求
    if (['get', 'head', 'options'].includes(method)) {
      return options;
    }
    
    // 添加CSRF令牌到请求头
    if (!options.headers) {
      options.headers = {};
    }
    
    options.headers[this.config.headerName] = this.sessionToken;
    
    // 双重提交Cookie验证
    if (this.config.enableDoubleSubmitCookies) {
      const cookieToken = this.getCookie(this.config.cookieName);
      if (cookieToken !== this.sessionToken) {
        throw new Error('CSRF token mismatch');
      }
    }
    
    // 验证来源
    if (this.config.enableOriginValidation && !this.validateOrigin()) {
      throw new Error('Invalid origin');
    }
    
    return options;
  }
  
  // 保护XMLHttpRequest
  protectXHR(xhr) {
    const originalSetRequestHeader = xhr.setRequestHeader;
    
    xhr.setRequestHeader = function(name, value) {
      originalSetRequestHeader.call(this, name, value);
    };
    
    // 添加CSRF令牌
    xhr.setRequestHeader(this.config.headerName, this.sessionToken);
  }
  
  // 验证来源
  validateOrigin() {
    const origin = window.location.origin;
    return this.config.trustedOrigins.includes(origin);
  }
  
  // 验证Referrer
  validateReferrer() {
    const referrer = document.referrer;
    
    if (!referrer) {
      // 某些情况下referrer可能为空,需要根据安全策略决定
      return this.config.allowEmptyReferrer || false;
    }
    
    try {
      const referrerUrl = new URL(referrer);
      const currentUrl = new URL(window.location.href);
      
      return referrerUrl.origin === currentUrl.origin;
    } catch {
      return false;
    }
  }
  
  // 处理CSRF攻击
  handleCSRFAttack(attack) {
    this.detectedAttacks.push({
      ...attack,
      timestamp: Date.now(),
      userAgent: navigator.userAgent,
      url: window.location.href,
      referrer: document.referrer
    });
    
    // 触发安全事件
    const event = new CustomEvent('csrf-attack-detected', {
      detail: attack
    });
    document.dispatchEvent(event);
    
    console.warn('🛡️ CSRF Attack Detected:', attack);
    
    // 刷新令牌
    this.refreshToken();
  }
  
  // 刷新令牌
  refreshToken() {
    this.generateSessionToken();
    this.addTokensToForms();
    
    console.log('🔄 CSRF token refreshed');
  }
  
  // 获取状态
  getStatus() {
    return {
      sessionToken: this.sessionToken ? '***' + this.sessionToken.slice(-4) : null,
      attacksDetected: this.detectedAttacks.length,
      lastAttack: this.detectedAttacks[this.detectedAttacks.length - 1],
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.tokens.clear();
    this.detectedAttacks = [];
    this.sessionToken = null;
  }
}

4. 点击劫持防护

4.1 点击劫持检测与防护

// 点击劫持保护模块
class ClickjackingProtection {
  constructor(config = {}) {
    this.config = {
      enableFrameBusting: true,
      enableXFrameOptions: true,
      enableCSPFrameAncestors: true,
      allowedFrameOrigins: [],
      enableClickTracking: true,
      suspiciousClickThreshold: 5,
      clickTimeWindow: 1000,
      ...config
    };
    
    this.clickHistory = [];
    this.suspiciousActivities = [];
    this.frameDetected = false;
    
    this.init();
  }
  
  // 初始化保护
  init() {
    this.detectFraming();
    this.setupFrameBusting();
    this.setupClickTracking();
    this.setupVisibilityDetection();
    this.setupCSPHeaders();
  }
  
  // 检测是否在iframe中
  detectFraming() {
    try {
      this.frameDetected = window.self !== window.top;
      
      if (this.frameDetected) {
        this.handleFrameDetection();
      }
    } catch (error) {
      // 跨域iframe会抛出异常
      this.frameDetected = true;
      this.handleFrameDetection();
    }
  }
  
  // 处理框架检测
  handleFrameDetection() {
    console.warn('🚨 Page loaded in frame detected');
    
    // 检查是否为允许的来源
    if (!this.isAllowedFrameOrigin()) {
      this.handleClickjackingAttempt({
        type: 'unauthorized_framing',
        parentOrigin: this.getParentOrigin(),
        timestamp: Date.now()
      });
    }
  }
  
  // 检查是否为允许的框架来源
  isAllowedFrameOrigin() {
    try {
      const parentOrigin = window.parent.location.origin;
      return this.config.allowedFrameOrigins.includes(parentOrigin);
    } catch {
      // 跨域情况下无法获取父窗口信息
      return false;
    }
  }
  
  // 获取父窗口来源
  getParentOrigin() {
    try {
      return window.parent.location.origin;
    } catch {
      return 'unknown';
    }
  }
  
  // 设置框架破坏
  setupFrameBusting() {
    if (!this.config.enableFrameBusting) return;
    
    // 经典的frame busting代码
    if (this.frameDetected && !this.isAllowedFrameOrigin()) {
      try {
        window.top.location = window.location;
      } catch {
        // 如果无法重定向,显示警告
        this.showFramingWarning();
      }
    }
    
    // 防止被重新框架化
    Object.defineProperty(window, 'top', {
      get: function() {
        return window;
      },
      configurable: false
    });
  }
  
  // 显示框架警告
  showFramingWarning() {
    const warning = document.createElement('div');
    warning.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(255, 0, 0, 0.9);
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 24px;
      font-weight: bold;
      z-index: 999999;
      text-align: center;
    `;
    
    warning.innerHTML = `
      <div>
        <h2>⚠️ Security Warning</h2>
        <p>This page is being displayed in an unauthorized frame.</p>
        <p>This may be a clickjacking attack.</p>
        <button onclick="window.open(window.location.href, '_blank')">Open in New Window</button>
      </div>
    `;
    
    document.body.appendChild(warning);
  }
  
  // 设置点击跟踪
  setupClickTracking() {
    if (!this.config.enableClickTracking) return;
    
    document.addEventListener('click', (event) => {
      this.trackClick(event);
    }, true); // 使用捕获阶段
    
    document.addEventListener('mousedown', (event) => {
      this.trackMouseDown(event);
    }, true);
  }
  
  // 跟踪点击
  trackClick(event) {
    const clickData = {
      timestamp: Date.now(),
      x: event.clientX,
      y: event.clientY,
      target: event.target.tagName,
      targetId: event.target.id,
      targetClass: event.target.className,
      button: event.button,
      ctrlKey: event.ctrlKey,
      shiftKey: event.shiftKey,
      altKey: event.altKey
    };
    
    this.clickHistory.push(clickData);
    
    // 保持点击历史在合理范围内
    if (this.clickHistory.length > 100) {
      this.clickHistory.shift();
    }
    
    // 分析点击模式
    this.analyzeClickPattern(clickData);
  }
  
  // 跟踪鼠标按下
  trackMouseDown(event) {
    // 检测是否在透明元素上点击
    const element = event.target;
    const computedStyle = window.getComputedStyle(element);
    
    if (computedStyle.opacity === '0' || computedStyle.visibility === 'hidden') {
      this.handleClickjackingAttempt({
        type: 'transparent_element_click',
        element: element.tagName,
        elementId: element.id,
        opacity: computedStyle.opacity,
        visibility: computedStyle.visibility,
        timestamp: Date.now()
      });
    }
  }
  
  // 分析点击模式
  analyzeClickPattern(clickData) {
    const recentClicks = this.clickHistory.filter(
      click => clickData.timestamp - click.timestamp < this.config.clickTimeWindow
    );
    
    // 检测快速连续点击
    if (recentClicks.length > this.config.suspiciousClickThreshold) {
      this.handleClickjackingAttempt({
        type: 'rapid_clicking',
        clickCount: recentClicks.length,
        timeWindow: this.config.clickTimeWindow,
        timestamp: Date.now()
      });
    }
    
    // 检测点击位置模式
    this.detectClickPositionPattern(recentClicks);
  }
  
  // 检测点击位置模式
  detectClickPositionPattern(clicks) {
    if (clicks.length < 3) return;
    
    // 检测是否所有点击都在同一位置(可能是自动化攻击)
    const firstClick = clicks[0];
    const samePosition = clicks.every(click => 
      Math.abs(click.x - firstClick.x) < 5 && 
      Math.abs(click.y - firstClick.y) < 5
    );
    
    if (samePosition && clicks.length > 3) {
      this.handleClickjackingAttempt({
        type: 'automated_clicking',
        position: { x: firstClick.x, y: firstClick.y },
        clickCount: clicks.length,
        timestamp: Date.now()
      });
    }
  }
  
  // 设置可见性检测
  setupVisibilityDetection() {
    // 检测页面可见性变化
    document.addEventListener('visibilitychange', () => {
      if (document.hidden && this.frameDetected) {
        this.handleClickjackingAttempt({
          type: 'visibility_manipulation',
          hidden: document.hidden,
          timestamp: Date.now()
        });
      }
    });
    
    // 检测窗口焦点变化
    window.addEventListener('blur', () => {
      if (this.frameDetected) {
        this.handleClickjackingAttempt({
          type: 'focus_manipulation',
          timestamp: Date.now()
        });
      }
    });
  }
  
  // 设置CSP头
  setupCSPHeaders() {
    if (!this.config.enableCSPFrameAncestors) return;
    
    // 检查是否已设置CSP
    const metaCSP = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
    
    if (!metaCSP) {
      const cspMeta = document.createElement('meta');
      cspMeta.httpEquiv = 'Content-Security-Policy';
      
      let frameAncestors = "frame-ancestors 'self'";
      if (this.config.allowedFrameOrigins.length > 0) {
        frameAncestors += ' ' + this.config.allowedFrameOrigins.join(' ');
      }
      
      cspMeta.content = frameAncestors;
      document.head.appendChild(cspMeta);
    }
  }
  
  // 验证点击
  validateClick(event) {
    // 检查点击是否在可疑区域
    const suspiciousAreas = this.identifySuspiciousAreas();
    
    for (const area of suspiciousAreas) {
      if (this.isClickInArea(event, area)) {
        this.handleClickjackingAttempt({
          type: 'suspicious_area_click',
          area: area,
          clickPosition: { x: event.clientX, y: event.clientY },
          timestamp: Date.now()
        });
        
        return false;
      }
    }
    
    return true;
  }
  
  // 识别可疑区域
  identifySuspiciousAreas() {
    const areas = [];
    
    // 查找透明或隐藏的可点击元素
    const clickableElements = document.querySelectorAll('a, button, input[type="submit"], input[type="button"]');
    
    clickableElements.forEach(element => {
      const style = window.getComputedStyle(element);
      const rect = element.getBoundingClientRect();
      
      if ((style.opacity === '0' || style.visibility === 'hidden') && 
          rect.width > 0 && rect.height > 0) {
        areas.push({
          element: element,
          rect: rect,
          reason: 'transparent_clickable'
        });
      }
    });
    
    return areas;
  }
  
  // 检查点击是否在区域内
  isClickInArea(event, area) {
    const rect = area.rect;
    return event.clientX >= rect.left && 
           event.clientX <= rect.right && 
           event.clientY >= rect.top && 
           event.clientY <= rect.bottom;
  }
  
  // 处理点击劫持攻击
  handleClickjackingAttempt(attempt) {
    this.suspiciousActivities.push(attempt);
    
    // 触发安全事件
    const event = new CustomEvent('clickjacking-detected', {
      detail: attempt
    });
    document.dispatchEvent(event);
    
    console.warn('🛡️ Clickjacking Attempt Detected:', attempt);
    
    // 根据攻击类型采取相应措施
    this.respondToAttack(attempt);
  }
  
  // 响应攻击
  respondToAttack(attempt) {
    switch (attempt.type) {
      case 'unauthorized_framing':
        if (this.config.enableFrameBusting) {
          this.showFramingWarning();
        }
        break;
        
      case 'rapid_clicking':
        this.temporarilyDisableClicks();
        break;
        
      case 'transparent_element_click':
        this.highlightSuspiciousElements();
        break;
    }
  }
  
  // 临时禁用点击
  temporarilyDisableClicks() {
    const overlay = document.createElement('div');
    overlay.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(255, 255, 0, 0.3);
      z-index: 999998;
      pointer-events: auto;
    `;
    
    overlay.innerHTML = `
      <div style="
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        background: white;
        padding: 20px;
        border-radius: 5px;
        box-shadow: 0 4px 6px rgba(0,0,0,0.1);
      ">
        <h3>⚠️ Suspicious Activity Detected</h3>
        <p>Rapid clicking detected. Please wait a moment.</p>
        <div id="countdown">5</div>
      </div>
    `;
    
    document.body.appendChild(overlay);
    
    let countdown = 5;
    const countdownElement = overlay.querySelector('#countdown');
    
    const timer = setInterval(() => {
      countdown--;
      countdownElement.textContent = countdown;
      
      if (countdown <= 0) {
        clearInterval(timer);
        overlay.remove();
      }
    }, 1000);
  }
  
  // 高亮可疑元素
  highlightSuspiciousElements() {
    const suspiciousAreas = this.identifySuspiciousAreas();
    
    suspiciousAreas.forEach(area => {
      const highlight = document.createElement('div');
      highlight.style.cssText = `
        position: absolute;
        border: 3px solid red;
        background: rgba(255, 0, 0, 0.2);
        pointer-events: none;
        z-index: 999997;
      `;
      
      const rect = area.rect;
      highlight.style.left = rect.left + 'px';
      highlight.style.top = rect.top + 'px';
      highlight.style.width = rect.width + 'px';
      highlight.style.height = rect.height + 'px';
      
      document.body.appendChild(highlight);
      
      // 5秒后移除高亮
      setTimeout(() => {
        highlight.remove();
      }, 5000);
    });
  }
  
  // 获取状态
  getStatus() {
    return {
      frameDetected: this.frameDetected,
      suspiciousActivities: this.suspiciousActivities.length,
      recentClicks: this.clickHistory.length,
      lastActivity: this.suspiciousActivities[this.suspiciousActivities.length - 1],
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.clickHistory = [];
    this.suspiciousActivities = [];
  }
}

5. 内容安全策略(CSP)

5.1 CSP策略管理

// 内容安全策略管理器
class ContentSecurityPolicyManager {
  constructor(config = {}) {
    this.config = {
      enableReporting: true,
      reportUri: '/csp-report',
      enableViolationLogging: true,
      strictMode: false,
      allowedSources: {
        script: ["'self'"],
        style: ["'self'", "'unsafe-inline'"],
        img: ["'self'", 'data:', 'https:'],
        connect: ["'self'"],
        font: ["'self'"],
        object: ["'none'"],
        media: ["'self'"],
        frame: ["'none'"]
      },
      ...config
    };
    
    this.violations = [];
    this.policies = new Map();
    this.dynamicNonces = new Set();
    
    this.init();
  }
  
  // 初始化CSP
  init() {
    this.generateCSPHeader();
    this.setupViolationReporting();
    this.setupDynamicNonces();
    this.monitorPolicyViolations();
  }
  
  // 生成CSP头
  generateCSPHeader() {
    const directives = [];
    
    // 基础指令
    directives.push(`default-src 'self'`);
    
    // 脚本源
    if (this.config.allowedSources.script.length > 0) {
      directives.push(`script-src ${this.config.allowedSources.script.join(' ')}`);
    }
    
    // 样式源
    if (this.config.allowedSources.style.length > 0) {
      directives.push(`style-src ${this.config.allowedSources.style.join(' ')}`);
    }
    
    // 图片源
    if (this.config.allowedSources.img.length > 0) {
      directives.push(`img-src ${this.config.allowedSources.img.join(' ')}`);
    }
    
    // 连接源
    if (this.config.allowedSources.connect.length > 0) {
      directives.push(`connect-src ${this.config.allowedSources.connect.join(' ')}`);
    }
    
    // 字体源
    if (this.config.allowedSources.font.length > 0) {
      directives.push(`font-src ${this.config.allowedSources.font.join(' ')}`);
    }
    
    // 对象源
    directives.push(`object-src ${this.config.allowedSources.object.join(' ')}`);
    
    // 媒体源
    if (this.config.allowedSources.media.length > 0) {
      directives.push(`media-src ${this.config.allowedSources.media.join(' ')}`);
    }
    
    // 框架源
    directives.push(`frame-src ${this.config.allowedSources.frame.join(' ')}`);
    
    // 框架祖先
    directives.push(`frame-ancestors 'self'`);
    
    // 基础URI
    directives.push(`base-uri 'self'`);
    
    // 表单动作
    directives.push(`form-action 'self'`);
    
    // 报告URI
    if (this.config.enableReporting) {
      directives.push(`report-uri ${this.config.reportUri}`);
    }
    
    const cspHeader = directives.join('; ');
    this.setCSPHeader(cspHeader);
    
    return cspHeader;
  }
  
  // 设置CSP头
  setCSPHeader(policy) {
    // 通过meta标签设置CSP
    let metaTag = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
    
    if (!metaTag) {
      metaTag = document.createElement('meta');
      metaTag.httpEquiv = 'Content-Security-Policy';
      document.head.appendChild(metaTag);
    }
    
    metaTag.content = policy;
    this.policies.set('main', policy);
  }
  
  // 设置违规报告
  setupViolationReporting() {
    if (!this.config.enableReporting) return;
    
    document.addEventListener('securitypolicyviolation', (event) => {
      this.handleViolation(event);
    });
  }
  
  // 处理CSP违规
  handleViolation(event) {
    const violation = {
      documentURI: event.documentURI,
      referrer: event.referrer,
      blockedURI: event.blockedURI,
      violatedDirective: event.violatedDirective,
      effectiveDirective: event.effectiveDirective,
      originalPolicy: event.originalPolicy,
      sourceFile: event.sourceFile,
      lineNumber: event.lineNumber,
      columnNumber: event.columnNumber,
      statusCode: event.statusCode,
      timestamp: Date.now()
    };
    
    this.violations.push(violation);
    
    if (this.config.enableViolationLogging) {
      console.warn('🛡️ CSP Violation:', violation);
    }
    
    // 触发违规事件
    const customEvent = new CustomEvent('csp-violation', {
      detail: violation
    });
    document.dispatchEvent(customEvent);
    
    // 发送违规报告
    this.sendViolationReport(violation);
  }
  
  // 发送违规报告
  async sendViolationReport(violation) {
    if (!this.config.reportUri) return;
    
    try {
      await fetch(this.config.reportUri, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          'csp-report': violation
        })
      });
    } catch (error) {
      console.error('Failed to send CSP violation report:', error);
    }
  }
  
  // 设置动态nonce
  setupDynamicNonces() {
    // 为内联脚本生成nonce
    this.generateNonce();
    
    // 监控新添加的脚本
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
          if (node.nodeType === Node.ELEMENT_NODE) {
            if (node.tagName === 'SCRIPT' && !node.src) {
              this.addNonceToScript(node);
            } else if (node.tagName === 'STYLE') {
              this.addNonceToStyle(node);
            }
          }
        });
      });
    });
    
    observer.observe(document.head, {
      childList: true,
      subtree: true
    });
  }
  
  // 生成nonce
  generateNonce() {
    const array = new Uint8Array(16);
    crypto.getRandomValues(array);
    const nonce = btoa(String.fromCharCode(...array));
    this.dynamicNonces.add(nonce);
    return nonce;
  }
  
  // 为脚本添加nonce
  addNonceToScript(script) {
    if (!script.nonce) {
      const nonce = this.generateNonce();
      script.nonce = nonce;
      
      // 更新CSP策略以包含新的nonce
      this.updateScriptSrcWithNonce(nonce);
    }
  }
  
  // 为样式添加nonce
  addNonceToStyle(style) {
    if (!style.nonce) {
      const nonce = this.generateNonce();
      style.nonce = nonce;
      
      // 更新CSP策略以包含新的nonce
      this.updateStyleSrcWithNonce(nonce);
    }
  }
  
  // 更新脚本源策略
  updateScriptSrcWithNonce(nonce) {
    const currentSources = this.config.allowedSources.script;
    const nonceSource = `'nonce-${nonce}'`;
    
    if (!currentSources.includes(nonceSource)) {
      currentSources.push(nonceSource);
      this.generateCSPHeader();
    }
  }
  
  // 更新样式源策略
  updateStyleSrcWithNonce(nonce) {
    const currentSources = this.config.allowedSources.style;
    const nonceSource = `'nonce-${nonce}'`;
    
    if (!currentSources.includes(nonceSource)) {
      currentSources.push(nonceSource);
      this.generateCSPHeader();
    }
  }
  
  // 监控策略违规
  monitorPolicyViolations() {
    // 检查现有脚本是否符合CSP
    const scripts = document.querySelectorAll('script');
    scripts.forEach(script => {
      if (!script.src && !script.nonce && script.innerHTML.trim()) {
        console.warn('Inline script without nonce detected:', script);
      }
    });
    
    // 检查现有样式是否符合CSP
    const styles = document.querySelectorAll('style');
    styles.forEach(style => {
      if (!style.nonce && style.innerHTML.trim()) {
        console.warn('Inline style without nonce detected:', style);
      }
    });
  }
  
  // 添加允许的源
  addAllowedSource(directive, source) {
    if (this.config.allowedSources[directive]) {
      if (!this.config.allowedSources[directive].includes(source)) {
        this.config.allowedSources[directive].push(source);
        this.generateCSPHeader();
      }
    }
  }
  
  // 移除允许的源
  removeAllowedSource(directive, source) {
    if (this.config.allowedSources[directive]) {
      const index = this.config.allowedSources[directive].indexOf(source);
      if (index > -1) {
        this.config.allowedSources[directive].splice(index, 1);
        this.generateCSPHeader();
      }
    }
  }
  
  // 验证资源
  validateResource(type, url) {
    const allowedSources = this.config.allowedSources[type] || [];
    
    // 检查是否为允许的源
    for (const source of allowedSources) {
      if (source === "'self'" && this.isSameOrigin(url)) {
        return true;
      }
      
      if (source === "'none'") {
        return false;
      }
      
      if (source.startsWith('http') && url.startsWith(source)) {
        return true;
      }
      
      if (source === 'data:' && url.startsWith('data:')) {
        return true;
      }
      
      if (source === 'https:' && url.startsWith('https:')) {
        return true;
      }
    }
    
    return false;
  }
  
  // 检查是否为同源
  isSameOrigin(url) {
    try {
      const urlObj = new URL(url, window.location.href);
      return urlObj.origin === window.location.origin;
    } catch {
      return false;
    }
  }
  
  // 获取违规统计
  getViolationStats() {
    const stats = {
      total: this.violations.length,
      byDirective: {},
      bySource: {},
      recent: this.violations.slice(-10)
    };
    
    this.violations.forEach(violation => {
      // 按指令统计
      const directive = violation.violatedDirective;
      stats.byDirective[directive] = (stats.byDirective[directive] || 0) + 1;
      
      // 按源统计
      const source = violation.blockedURI;
      stats.bySource[source] = (stats.bySource[source] || 0) + 1;
    });
    
    return stats;
  }
  
  // 获取状态
  getStatus() {
    return {
      policies: Object.fromEntries(this.policies),
      violations: this.violations.length,
      nonces: this.dynamicNonces.size,
      config: this.config,
      stats: this.getViolationStats()
    };
  }
  
  // 清理
  cleanup() {
    this.violations = [];
    this.policies.clear();
    this.dynamicNonces.clear();
  }
}

6. 输入验证与数据清理

6.1 输入验证管理器

// 输入验证管理器
class InputValidationManager {
  constructor(config = {}) {
    this.config = {
      enableRealTimeValidation: true,
      enableSanitization: true,
      maxInputLength: 10000,
      allowedTags: ['b', 'i', 'em', 'strong', 'p', 'br'],
      allowedAttributes: ['class', 'id'],
      enableCSRFValidation: true,
      enableRateLimiting: true,
      rateLimitWindow: 60000, // 1分钟
      rateLimitMax: 100,
      ...config
    };
    
    this.validators = new Map();
    this.sanitizers = new Map();
    this.inputHistory = [];
    this.rateLimitData = new Map();
    
    this.init();
  }
  
  // 初始化
  init() {
    this.setupDefaultValidators();
    this.setupDefaultSanitizers();
    this.setupInputMonitoring();
    this.setupRateLimiting();
  }
  
  // 设置默认验证器
  setupDefaultValidators() {
    // 邮箱验证
    this.addValidator('email', (value) => {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return emailRegex.test(value);
    });
    
    // URL验证
    this.addValidator('url', (value) => {
      try {
        new URL(value);
        return true;
      } catch {
        return false;
      }
    });
    
    // 电话号码验证
    this.addValidator('phone', (value) => {
      const phoneRegex = /^[\+]?[1-9][\d]{0,15}$/;
      return phoneRegex.test(value.replace(/[\s\-\(\)]/g, ''));
    });
    
    // 数字验证
    this.addValidator('number', (value) => {
      return !isNaN(value) && isFinite(value);
    });
    
    // 整数验证
    this.addValidator('integer', (value) => {
      return Number.isInteger(Number(value));
    });
    
    // 日期验证
    this.addValidator('date', (value) => {
      const date = new Date(value);
      return date instanceof Date && !isNaN(date);
    });
    
    // 密码强度验证
    this.addValidator('password', (value) => {
      // 至少8位,包含大小写字母、数字和特殊字符
      const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
      return passwordRegex.test(value);
    });
    
    // SQL注入检测
    this.addValidator('sql-safe', (value) => {
      const sqlPatterns = [
        /('|(\-\-)|(;)|(\||\|)|(\*|\*))/i,
        /(union|select|insert|delete|update|drop|create|alter|exec|execute)/i
      ];
      
      return !sqlPatterns.some(pattern => pattern.test(value));
    });
    
    // XSS检测
    this.addValidator('xss-safe', (value) => {
      const xssPatterns = [
        /<script[^>]*>.*?<\/script>/gi,
        /<iframe[^>]*>.*?<\/iframe>/gi,
        /javascript:/gi,
        /on\w+\s*=/gi,
        /<object[^>]*>.*?<\/object>/gi,
        /<embed[^>]*>.*?<\/embed>/gi
      ];
      
      return !xssPatterns.some(pattern => pattern.test(value));
    });
  }
  
  // 设置默认清理器
  setupDefaultSanitizers() {
    // HTML清理
    this.addSanitizer('html', (value) => {
      return this.sanitizeHTML(value);
    });
    
    // 移除脚本标签
    this.addSanitizer('remove-scripts', (value) => {
      return value.replace(/<script[^>]*>.*?<\/script>/gi, '');
    });
    
    // 移除事件处理器
    this.addSanitizer('remove-events', (value) => {
      return value.replace(/on\w+\s*=\s*["'][^"']*["']/gi, '');
    });
    
    // 移除危险协议
    this.addSanitizer('safe-urls', (value) => {
      return value.replace(/(javascript|data|vbscript):/gi, '');
    });
    
    // 转义HTML实体
    this.addSanitizer('escape-html', (value) => {
      const div = document.createElement('div');
      div.textContent = value;
      return div.innerHTML;
    });
    
    // 移除多余空白
    this.addSanitizer('trim-whitespace', (value) => {
      return value.replace(/\s+/g, ' ').trim();
    });
  }
  
  // 设置输入监控
  setupInputMonitoring() {
    if (!this.config.enableRealTimeValidation) return;
    
    // 监控所有输入元素
    document.addEventListener('input', (event) => {
      if (event.target.matches('input, textarea, select')) {
        this.validateInput(event.target);
      }
    });
    
    // 监控表单提交
    document.addEventListener('submit', (event) => {
      if (event.target.tagName === 'FORM') {
        if (!this.validateForm(event.target)) {
          event.preventDefault();
        }
      }
    });
  }
  
  // 设置速率限制
  setupRateLimiting() {
    if (!this.config.enableRateLimiting) return;
    
    document.addEventListener('input', (event) => {
      if (event.target.matches('input, textarea')) {
        this.checkRateLimit(event.target);
      }
    });
  }
  
  // 添加验证器
  addValidator(name, validator) {
    this.validators.set(name, validator);
  }
  
  // 添加清理器
  addSanitizer(name, sanitizer) {
    this.sanitizers.set(name, sanitizer);
  }
  
  // 验证输入
  validateInput(input) {
    const value = input.value;
    const validationRules = this.getValidationRules(input);
    const errors = [];
    
    // 长度检查
    if (value.length > this.config.maxInputLength) {
      errors.push(`Input too long (max: ${this.config.maxInputLength})`);
    }
    
    // 应用验证规则
    validationRules.forEach(rule => {
      const validator = this.validators.get(rule);
      if (validator && !validator(value)) {
        errors.push(`Validation failed: ${rule}`);
      }
    });
    
    // 显示验证结果
    this.displayValidationResult(input, errors);
    
    // 记录输入历史
    this.recordInput(input, value, errors);
    
    return errors.length === 0;
  }
  
  // 获取验证规则
  getValidationRules(input) {
    const rules = [];
    
    // 从data属性获取规则
    if (input.dataset.validate) {
      rules.push(...input.dataset.validate.split(','));
    }
    
    // 根据输入类型添加默认规则
    switch (input.type) {
      case 'email':
        rules.push('email');
        break;
      case 'url':
        rules.push('url');
        break;
      case 'tel':
        rules.push('phone');
        break;
      case 'number':
        rules.push('number');
        break;
      case 'password':
        rules.push('password');
        break;
    }
    
    // 安全检查
    rules.push('xss-safe', 'sql-safe');
    
    return rules;
  }
  
  // 显示验证结果
  displayValidationResult(input, errors) {
    // 移除现有错误提示
    const existingError = input.parentNode.querySelector('.validation-error');
    if (existingError) {
      existingError.remove();
    }
    
    // 更新输入样式
    if (errors.length > 0) {
      input.classList.add('invalid');
      input.classList.remove('valid');
      
      // 显示错误信息
      const errorDiv = document.createElement('div');
      errorDiv.className = 'validation-error';
      errorDiv.style.cssText = 'color: red; font-size: 12px; margin-top: 2px;';
      errorDiv.textContent = errors[0]; // 只显示第一个错误
      
      input.parentNode.insertBefore(errorDiv, input.nextSibling);
    } else {
      input.classList.add('valid');
      input.classList.remove('invalid');
    }
  }
  
  // 验证表单
  validateForm(form) {
    const inputs = form.querySelectorAll('input, textarea, select');
    let isValid = true;
    
    inputs.forEach(input => {
      if (!this.validateInput(input)) {
        isValid = false;
      }
    });
    
    return isValid;
  }
  
  // 清理输入
  sanitizeInput(value, sanitizers = ['html', 'remove-scripts', 'remove-events']) {
    let sanitized = value;
    
    sanitizers.forEach(sanitizerName => {
      const sanitizer = this.sanitizers.get(sanitizerName);
      if (sanitizer) {
        sanitized = sanitizer(sanitized);
      }
    });
    
    return sanitized;
  }
  
  // HTML清理
  sanitizeHTML(html) {
    const div = document.createElement('div');
    div.innerHTML = html;
    
    // 移除不允许的标签
    const allElements = div.querySelectorAll('*');
    allElements.forEach(element => {
      if (!this.config.allowedTags.includes(element.tagName.toLowerCase())) {
        element.remove();
      } else {
        // 移除不允许的属性
        const attributes = Array.from(element.attributes);
        attributes.forEach(attr => {
          if (!this.config.allowedAttributes.includes(attr.name)) {
            element.removeAttribute(attr.name);
          }
        });
      }
    });
    
    return div.innerHTML;
  }
  
  // 检查速率限制
  checkRateLimit(input) {
    const now = Date.now();
    const key = input.name || input.id || 'anonymous';
    
    if (!this.rateLimitData.has(key)) {
      this.rateLimitData.set(key, []);
    }
    
    const timestamps = this.rateLimitData.get(key);
    
    // 移除过期的时间戳
    const validTimestamps = timestamps.filter(
      timestamp => now - timestamp < this.config.rateLimitWindow
    );
    
    validTimestamps.push(now);
    this.rateLimitData.set(key, validTimestamps);
    
    // 检查是否超过限制
    if (validTimestamps.length > this.config.rateLimitMax) {
      this.handleRateLimitExceeded(input);
      return false;
    }
    
    return true;
  }
  
  // 处理速率限制超出
  handleRateLimitExceeded(input) {
    input.disabled = true;
    input.placeholder = 'Rate limit exceeded. Please wait...';
    
    // 显示警告
    const warning = document.createElement('div');
    warning.className = 'rate-limit-warning';
    warning.style.cssText = 'color: orange; font-size: 12px; margin-top: 2px;';
    warning.textContent = 'Too many inputs. Please slow down.';
    
    input.parentNode.insertBefore(warning, input.nextSibling);
    
    // 30秒后恢复
    setTimeout(() => {
      input.disabled = false;
      input.placeholder = '';
      warning.remove();
    }, 30000);
  }
  
  // 记录输入
  recordInput(input, value, errors) {
    this.inputHistory.push({
      element: input.name || input.id,
      value: value.substring(0, 100), // 只记录前100个字符
      errors: errors,
      timestamp: Date.now()
    });
    
    // 保持历史记录在合理范围内
    if (this.inputHistory.length > 1000) {
      this.inputHistory.shift();
    }
  }
  
  // 获取输入统计
  getInputStats() {
    const stats = {
      totalInputs: this.inputHistory.length,
      errorCount: this.inputHistory.filter(input => input.errors.length > 0).length,
      rateLimitViolations: 0,
      recentErrors: this.inputHistory.filter(input => 
        input.errors.length > 0 && 
        Date.now() - input.timestamp < 300000 // 5分钟内
      )
    };
    
    return stats;
  }
  
  // 获取状态
  getStatus() {
    return {
      validators: Array.from(this.validators.keys()),
      sanitizers: Array.from(this.sanitizers.keys()),
      inputHistory: this.inputHistory.length,
      rateLimitData: this.rateLimitData.size,
      stats: this.getInputStats(),
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.inputHistory = [];
    this.rateLimitData.clear();
  }
}

7. 安全存储管理

7.1 安全存储管理器

// 安全存储管理器
class SecureStorageManager {
  constructor(config = {}) {
    this.config = {
      enableEncryption: true,
      encryptionKey: null,
      enableCompression: true,
      enableExpiration: true,
      defaultTTL: 3600000, // 1小时
      enableIntegrityCheck: true,
      enableSecureTransport: true,
      storageQuotaLimit: 5 * 1024 * 1024, // 5MB
      ...config
    };
    
    this.encryptionKey = null;
    this.storageUsage = new Map();
    this.accessLog = [];
    
    this.init();
  }
  
  // 初始化
  async init() {
    await this.initializeEncryption();
    this.setupStorageMonitoring();
    this.setupQuotaManagement();
    this.cleanupExpiredData();
  }
  
  // 初始化加密
  async initializeEncryption() {
    if (!this.config.enableEncryption) return;
    
    try {
      // 生成或获取加密密钥
      if (this.config.encryptionKey) {
        this.encryptionKey = await this.importKey(this.config.encryptionKey);
      } else {
        this.encryptionKey = await this.generateKey();
      }
    } catch (error) {
      console.error('Failed to initialize encryption:', error);
      this.config.enableEncryption = false;
    }
  }
  
  // 生成加密密钥
  async generateKey() {
    return await crypto.subtle.generateKey(
      {
        name: 'AES-GCM',
        length: 256
      },
      true,
      ['encrypt', 'decrypt']
    );
  }
  
  // 导入密钥
  async importKey(keyData) {
    return await crypto.subtle.importKey(
      'raw',
      keyData,
      {
        name: 'AES-GCM',
        length: 256
      },
      true,
      ['encrypt', 'decrypt']
    );
  }
  
  // 加密数据
  async encryptData(data) {
    if (!this.config.enableEncryption || !this.encryptionKey) {
      return data;
    }
    
    try {
      const encoder = new TextEncoder();
      const dataBuffer = encoder.encode(JSON.stringify(data));
      
      const iv = crypto.getRandomValues(new Uint8Array(12));
      
      const encryptedBuffer = await crypto.subtle.encrypt(
        {
          name: 'AES-GCM',
          iv: iv
        },
        this.encryptionKey,
        dataBuffer
      );
      
      // 组合IV和加密数据
      const combined = new Uint8Array(iv.length + encryptedBuffer.byteLength);
      combined.set(iv);
      combined.set(new Uint8Array(encryptedBuffer), iv.length);
      
      return btoa(String.fromCharCode(...combined));
    } catch (error) {
      console.error('Encryption failed:', error);
      return data;
    }
  }
  
  // 解密数据
  async decryptData(encryptedData) {
    if (!this.config.enableEncryption || !this.encryptionKey || typeof encryptedData !== 'string') {
      return encryptedData;
    }
    
    try {
      const combined = new Uint8Array(
        atob(encryptedData).split('').map(char => char.charCodeAt(0))
      );
      
      const iv = combined.slice(0, 12);
      const encryptedBuffer = combined.slice(12);
      
      const decryptedBuffer = await crypto.subtle.decrypt(
        {
          name: 'AES-GCM',
          iv: iv
        },
        this.encryptionKey,
        encryptedBuffer
      );
      
      const decoder = new TextDecoder();
      const decryptedText = decoder.decode(decryptedBuffer);
      
      return JSON.parse(decryptedText);
    } catch (error) {
      console.error('Decryption failed:', error);
      return null;
    }
  }
  
  // 压缩数据
  compressData(data) {
    if (!this.config.enableCompression) return data;
    
    try {
      // 简单的字符串压缩(实际项目中可使用更好的压缩算法)
      const jsonString = JSON.stringify(data);
      return this.simpleCompress(jsonString);
    } catch (error) {
      console.error('Compression failed:', error);
      return data;
    }
  }
  
  // 解压数据
  decompressData(compressedData) {
    if (!this.config.enableCompression || typeof compressedData !== 'string') {
      return compressedData;
    }
    
    try {
      const decompressed = this.simpleDecompress(compressedData);
      return JSON.parse(decompressed);
    } catch (error) {
      console.error('Decompression failed:', error);
      return compressedData;
    }
  }
  
  // 简单压缩算法
  simpleCompress(str) {
    const compressed = [];
    let i = 0;
    
    while (i < str.length) {
      let match = '';
      let matchLength = 0;
      
      // 查找重复模式
      for (let j = i + 1; j < Math.min(i + 255, str.length); j++) {
        const pattern = str.substring(i, j);
        const nextOccurrence = str.indexOf(pattern, j);
        
        if (nextOccurrence !== -1 && pattern.length > matchLength) {
          match = pattern;
          matchLength = pattern.length;
        }
      }
      
      if (matchLength > 3) {
        compressed.push(`[${matchLength}:${match}]`);
        i += matchLength;
      } else {
        compressed.push(str[i]);
        i++;
      }
    }
    
    return compressed.join('');
  }
  
  // 简单解压算法
  simpleDecompress(compressed) {
    return compressed.replace(/\[(\d+):([^\]]+)\]/g, (match, length, pattern) => {
      return pattern;
    });
  }
  
  // 创建数据包装器
  createDataWrapper(data) {
    const wrapper = {
      data: data,
      timestamp: Date.now(),
      version: '1.0'
    };
    
    if (this.config.enableExpiration) {
      wrapper.expiresAt = Date.now() + this.config.defaultTTL;
    }
    
    if (this.config.enableIntegrityCheck) {
      wrapper.checksum = this.calculateChecksum(data);
    }
    
    return wrapper;
  }
  
  // 计算校验和
  calculateChecksum(data) {
    const str = JSON.stringify(data);
    let hash = 0;
    
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    
    return hash.toString(36);
  }
  
  // 验证数据完整性
  verifyIntegrity(wrapper) {
    if (!this.config.enableIntegrityCheck || !wrapper.checksum) {
      return true;
    }
    
    const calculatedChecksum = this.calculateChecksum(wrapper.data);
    return calculatedChecksum === wrapper.checksum;
  }
  
  // 检查数据是否过期
  isExpired(wrapper) {
    if (!this.config.enableExpiration || !wrapper.expiresAt) {
      return false;
    }
    
    return Date.now() > wrapper.expiresAt;
  }
  
  // 安全存储数据
  async setItem(key, value, options = {}) {
    try {
      // 检查存储配额
      if (!this.checkStorageQuota(key, value)) {
        throw new Error('Storage quota exceeded');
      }
      
      // 创建数据包装器
      const wrapper = this.createDataWrapper(value);
      
      // 应用过期时间选项
      if (options.ttl) {
        wrapper.expiresAt = Date.now() + options.ttl;
      }
      
      // 压缩数据
      let processedData = this.compressData(wrapper);
      
      // 加密数据
      processedData = await this.encryptData(processedData);
      
      // 选择存储方式
      const storage = options.secure ? this.getSecureStorage() : localStorage;
      storage.setItem(key, JSON.stringify(processedData));
      
      // 记录存储使用情况
      this.recordStorageUsage(key, JSON.stringify(processedData).length);
      
      // 记录访问日志
      this.logAccess('set', key);
      
      return true;
    } catch (error) {
      console.error('Failed to store data:', error);
      return false;
    }
  }
  
  // 安全获取数据
  async getItem(key, options = {}) {
    try {
      // 选择存储方式
      const storage = options.secure ? this.getSecureStorage() : localStorage;
      const storedData = storage.getItem(key);
      
      if (!storedData) {
        return null;
      }
      
      // 解析存储的数据
      let processedData = JSON.parse(storedData);
      
      // 解密数据
      processedData = await this.decryptData(processedData);
      
      // 解压数据
      const wrapper = this.decompressData(processedData);
      
      // 检查数据完整性
      if (!this.verifyIntegrity(wrapper)) {
        console.warn('Data integrity check failed for key:', key);
        this.removeItem(key, options);
        return null;
      }
      
      // 检查是否过期
      if (this.isExpired(wrapper)) {
        this.removeItem(key, options);
        return null;
      }
      
      // 记录访问日志
      this.logAccess('get', key);
      
      return wrapper.data;
    } catch (error) {
      console.error('Failed to retrieve data:', error);
      return null;
    }
  }
  
  // 移除数据
  removeItem(key, options = {}) {
    try {
      const storage = options.secure ? this.getSecureStorage() : localStorage;
      storage.removeItem(key);
      
      // 更新存储使用情况
      this.storageUsage.delete(key);
      
      // 记录访问日志
      this.logAccess('remove', key);
      
      return true;
    } catch (error) {
      console.error('Failed to remove data:', error);
      return false;
    }
  }
  
  // 获取安全存储
  getSecureStorage() {
    // 在实际应用中,这里可以返回更安全的存储方式
    // 比如IndexedDB或者内存存储
    return sessionStorage;
  }
  
  // 检查存储配额
  checkStorageQuota(key, value) {
    const dataSize = JSON.stringify(value).length;
    const currentUsage = this.getCurrentStorageUsage();
    
    if (currentUsage + dataSize > this.config.storageQuotaLimit) {
      // 尝试清理过期数据
      this.cleanupExpiredData();
      
      // 重新检查
      const newUsage = this.getCurrentStorageUsage();
      if (newUsage + dataSize > this.config.storageQuotaLimit) {
        return false;
      }
    }
    
    return true;
  }
  
  // 获取当前存储使用情况
  getCurrentStorageUsage() {
    let totalSize = 0;
    
    for (const [key, size] of this.storageUsage) {
      totalSize += size;
    }
    
    return totalSize;
  }
  
  // 记录存储使用情况
  recordStorageUsage(key, size) {
    this.storageUsage.set(key, size);
  }
  
  // 设置存储监控
  setupStorageMonitoring() {
    // 监控存储事件
    window.addEventListener('storage', (event) => {
      this.logAccess('external_change', event.key);
    });
  }
  
  // 设置配额管理
  setupQuotaManagement() {
    // 定期检查存储使用情况
    setInterval(() => {
      const usage = this.getCurrentStorageUsage();
      const limit = this.config.storageQuotaLimit;
      
      if (usage > limit * 0.8) {
        console.warn('Storage usage approaching limit:', usage, '/', limit);
        this.cleanupExpiredData();
      }
    }, 60000); // 每分钟检查一次
  }
  
  // 清理过期数据
  async cleanupExpiredData() {
    const keys = Object.keys(localStorage);
    
    for (const key of keys) {
      try {
        const data = await this.getItem(key);
        // getItem会自动处理过期数据的清理
      } catch (error) {
        // 如果数据损坏,直接删除
        localStorage.removeItem(key);
        this.storageUsage.delete(key);
      }
    }
  }
  
  // 记录访问日志
  logAccess(action, key) {
    this.accessLog.push({
      action: action,
      key: key,
      timestamp: Date.now(),
      userAgent: navigator.userAgent
    });
    
    // 保持日志在合理范围内
    if (this.accessLog.length > 1000) {
      this.accessLog.shift();
    }
  }
  
  // 获取存储统计
  getStorageStats() {
    return {
      totalKeys: this.storageUsage.size,
      totalSize: this.getCurrentStorageUsage(),
      quotaLimit: this.config.storageQuotaLimit,
      usagePercentage: (this.getCurrentStorageUsage() / this.config.storageQuotaLimit) * 100,
      accessLog: this.accessLog.length,
      recentAccess: this.accessLog.slice(-10)
    };
  }
  
  // 获取状态
  getStatus() {
    return {
      encryptionEnabled: this.config.enableEncryption,
      compressionEnabled: this.config.enableCompression,
      expirationEnabled: this.config.enableExpiration,
      integrityCheckEnabled: this.config.enableIntegrityCheck,
      stats: this.getStorageStats(),
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.storageUsage.clear();
    this.accessLog = [];
  }
}

8. 安全通信管理

8.1 安全通信管理器

// 安全通信管理器
class SecureCommunicationManager {
  constructor(config = {}) {
    this.config = {
      enableHTTPS: true,
      enableCertificatePinning: true,
      enableRequestSigning: true,
      enableResponseValidation: true,
      enableRateLimiting: true,
      maxRequestsPerMinute: 60,
      enableRequestLogging: true,
      trustedDomains: [],
      blockedDomains: [],
      enableCSRFProtection: true,
      enableCORS: true,
      allowedOrigins: [],
      ...config
    };
    
    this.requestHistory = [];
    this.rateLimitData = new Map();
    this.trustedCertificates = new Set();
    this.blockedRequests = [];
    
    this.init();
  }
  
  // 初始化
  init() {
    this.setupRequestInterception();
    this.setupResponseValidation();
    this.setupRateLimiting();
    this.setupCertificatePinning();
    this.setupCSRFProtection();
  }
  
  // 设置请求拦截
  setupRequestInterception() {
    // 拦截fetch请求
    const originalFetch = window.fetch;
    
    window.fetch = async (url, options = {}) => {
      try {
        // 验证请求
        const validationResult = await this.validateRequest(url, options);
        if (!validationResult.isValid) {
          throw new Error(`Request blocked: ${validationResult.reason}`);
        }
        
        // 应用安全选项
        const secureOptions = this.applySecurityOptions(options);
        
        // 记录请求
        this.logRequest(url, secureOptions);
        
        // 执行请求
        const response = await originalFetch(url, secureOptions);
        
        // 验证响应
        const responseValidation = await this.validateResponse(response);
        if (!responseValidation.isValid) {
          throw new Error(`Response validation failed: ${responseValidation.reason}`);
        }
        
        return response;
      } catch (error) {
        this.handleRequestError(url, options, error);
        throw error;
      }
    };
    
    // 拦截XMLHttpRequest
    const originalXHROpen = XMLHttpRequest.prototype.open;
    const originalXHRSend = XMLHttpRequest.prototype.send;
    
    XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
      this._secureUrl = url;
      this._secureMethod = method;
      return originalXHROpen.call(this, method, url, async, user, password);
    };
    
    XMLHttpRequest.prototype.send = function(data) {
      const manager = window.secureCommunicationManager;
      if (manager) {
        const validationResult = manager.validateRequestSync(this._secureUrl, {
          method: this._secureMethod,
          body: data
        });
        
        if (!validationResult.isValid) {
          throw new Error(`XHR Request blocked: ${validationResult.reason}`);
        }
        
        manager.logRequest(this._secureUrl, {
          method: this._secureMethod,
          body: data
        });
      }
      
      return originalXHRSend.call(this, data);
    };
  }
  
  // 验证请求
  async validateRequest(url, options) {
    try {
      const urlObj = new URL(url, window.location.href);
      
      // 检查HTTPS
      if (this.config.enableHTTPS && urlObj.protocol !== 'https:' && urlObj.hostname !== 'localhost') {
        return {
          isValid: false,
          reason: 'HTTPS required for external requests'
        };
      }
      
      // 检查域名白名单
      if (this.config.trustedDomains.length > 0) {
        const isTrusted = this.config.trustedDomains.some(domain => 
          urlObj.hostname === domain || urlObj.hostname.endsWith('.' + domain)
        );
        
        if (!isTrusted) {
          return {
            isValid: false,
            reason: 'Domain not in trusted list'
          };
        }
      }
      
      // 检查域名黑名单
      if (this.config.blockedDomains.length > 0) {
        const isBlocked = this.config.blockedDomains.some(domain => 
          urlObj.hostname === domain || urlObj.hostname.endsWith('.' + domain)
        );
        
        if (isBlocked) {
          return {
            isValid: false,
            reason: 'Domain is blocked'
          };
        }
      }
      
      // 检查速率限制
      if (this.config.enableRateLimiting) {
        const rateLimitResult = this.checkRateLimit(urlObj.hostname);
        if (!rateLimitResult.allowed) {
          return {
            isValid: false,
            reason: 'Rate limit exceeded'
          };
        }
      }
      
      // 检查请求内容
      if (options.body) {
        const contentValidation = this.validateRequestContent(options.body);
        if (!contentValidation.isValid) {
          return contentValidation;
        }
      }
      
      return { isValid: true };
    } catch (error) {
      return {
        isValid: false,
        reason: `Validation error: ${error.message}`
      };
    }
  }
  
  // 同步验证请求(用于XHR)
  validateRequestSync(url, options) {
    try {
      const urlObj = new URL(url, window.location.href);
      
      // 基本验证(简化版)
      if (this.config.enableHTTPS && urlObj.protocol !== 'https:' && urlObj.hostname !== 'localhost') {
        return {
          isValid: false,
          reason: 'HTTPS required'
        };
      }
      
      return { isValid: true };
    } catch (error) {
      return {
        isValid: false,
        reason: error.message
      };
    }
  }
  
  // 验证请求内容
  validateRequestContent(body) {
    if (typeof body === 'string') {
      // 检查敏感信息
      const sensitivePatterns = [
        /password\s*[=:]\s*["']?[^"'\s]+/i,
        /api[_-]?key\s*[=:]\s*["']?[^"'\s]+/i,
        /secret\s*[=:]\s*["']?[^"'\s]+/i,
        /token\s*[=:]\s*["']?[^"'\s]+/i
      ];
      
      for (const pattern of sensitivePatterns) {
        if (pattern.test(body)) {
          return {
            isValid: false,
            reason: 'Sensitive information detected in request body'
          };
        }
      }
      
      // 检查SQL注入
      const sqlPatterns = [
        /(union|select|insert|delete|update|drop|create|alter)\s+/i,
        /('|(\-\-)|(;)|(\||\|)|(\*|\*))/
      ];
      
      for (const pattern of sqlPatterns) {
        if (pattern.test(body)) {
          return {
            isValid: false,
            reason: 'Potential SQL injection detected'
          };
        }
      }
    }
    
    return { isValid: true };
  }
  
  // 应用安全选项
  applySecurityOptions(options) {
    const secureOptions = { ...options };
    
    // 设置默认headers
    if (!secureOptions.headers) {
      secureOptions.headers = {};
    }
    
    // 添加安全headers
    secureOptions.headers['X-Requested-With'] = 'XMLHttpRequest';
    secureOptions.headers['Cache-Control'] = 'no-cache';
    
    // CSRF保护
    if (this.config.enableCSRFProtection) {
      const csrfToken = this.getCSRFToken();
      if (csrfToken) {
        secureOptions.headers['X-CSRF-Token'] = csrfToken;
      }
    }
    
    // 设置credentials
    if (!secureOptions.credentials) {
      secureOptions.credentials = 'same-origin';
    }
    
    // 请求签名
    if (this.config.enableRequestSigning) {
      const signature = this.signRequest(secureOptions);
      secureOptions.headers['X-Request-Signature'] = signature;
    }
    
    return secureOptions;
  }
  
  // 获取CSRF令牌
  getCSRFToken() {
    // 从meta标签获取
    const metaTag = document.querySelector('meta[name="csrf-token"]');
    if (metaTag) {
      return metaTag.getAttribute('content');
    }
    
    // 从cookie获取
    const cookies = document.cookie.split(';');
    for (const cookie of cookies) {
      const [name, value] = cookie.trim().split('=');
      if (name === 'XSRF-TOKEN' || name === 'csrf_token') {
        return decodeURIComponent(value);
      }
    }
    
    return null;
  }
  
  // 签名请求
  signRequest(options) {
    const timestamp = Date.now();
    const method = options.method || 'GET';
    const body = options.body || '';
    
    // 创建签名字符串
    const signatureString = `${method}:${timestamp}:${body}`;
    
    // 简单的哈希签名(实际项目中应使用更安全的签名算法)
    let hash = 0;
    for (let i = 0; i < signatureString.length; i++) {
      const char = signatureString.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash;
    }
    
    return `${timestamp}.${hash.toString(36)}`;
  }
  
  // 设置响应验证
  setupResponseValidation() {
    // 响应验证在fetch拦截中处理
  }
  
  // 验证响应
  async validateResponse(response) {
    try {
      // 检查状态码
      if (!response.ok) {
        return {
          isValid: false,
          reason: `HTTP error: ${response.status} ${response.statusText}`
        };
      }
      
      // 检查Content-Type
      const contentType = response.headers.get('Content-Type');
      if (contentType && !this.isAllowedContentType(contentType)) {
        return {
          isValid: false,
          reason: `Disallowed content type: ${contentType}`
        };
      }
      
      // 检查安全headers
      const securityHeaders = [
        'X-Content-Type-Options',
        'X-Frame-Options',
        'X-XSS-Protection'
      ];
      
      const missingHeaders = securityHeaders.filter(header => 
        !response.headers.has(header)
      );
      
      if (missingHeaders.length > 0) {
        console.warn('Missing security headers:', missingHeaders);
      }
      
      return { isValid: true };
    } catch (error) {
      return {
        isValid: false,
        reason: `Response validation error: ${error.message}`
      };
    }
  }
  
  // 检查允许的内容类型
  isAllowedContentType(contentType) {
    const allowedTypes = [
      'application/json',
      'text/html',
      'text/plain',
      'text/css',
      'text/javascript',
      'application/javascript',
      'image/',
      'font/'
    ];
    
    return allowedTypes.some(type => contentType.includes(type));
  }
  
  // 设置速率限制
  setupRateLimiting() {
    if (!this.config.enableRateLimiting) return;
    
    // 定期清理过期的速率限制数据
    setInterval(() => {
      this.cleanupRateLimitData();
    }, 60000); // 每分钟清理一次
  }
  
  // 检查速率限制
  checkRateLimit(hostname) {
    if (!this.config.enableRateLimiting) {
      return { allowed: true };
    }
    
    const now = Date.now();
    const windowStart = now - 60000; // 1分钟窗口
    
    if (!this.rateLimitData.has(hostname)) {
      this.rateLimitData.set(hostname, []);
    }
    
    const requests = this.rateLimitData.get(hostname);
    
    // 移除过期请求
    const validRequests = requests.filter(timestamp => timestamp > windowStart);
    
    // 检查是否超过限制
    if (validRequests.length >= this.config.maxRequestsPerMinute) {
      return {
        allowed: false,
        resetTime: Math.min(...validRequests) + 60000
      };
    }
    
    // 添加当前请求
    validRequests.push(now);
    this.rateLimitData.set(hostname, validRequests);
    
    return { allowed: true };
  }
  
  // 清理速率限制数据
  cleanupRateLimitData() {
    const now = Date.now();
    const windowStart = now - 60000;
    
    for (const [hostname, requests] of this.rateLimitData) {
      const validRequests = requests.filter(timestamp => timestamp > windowStart);
      
      if (validRequests.length === 0) {
        this.rateLimitData.delete(hostname);
      } else {
        this.rateLimitData.set(hostname, validRequests);
      }
    }
  }
  
  // 设置证书固定
  setupCertificatePinning() {
    if (!this.config.enableCertificatePinning) return;
    
    // 在实际应用中,这里会实现证书固定逻辑
    // 由于浏览器限制,这里只是示例
    console.log('Certificate pinning enabled');
  }
  
  // 设置CSRF保护
  setupCSRFProtection() {
    if (!this.config.enableCSRFProtection) return;
    
    // 确保CSRF令牌存在
    if (!this.getCSRFToken()) {
      console.warn('CSRF token not found. CSRF protection may not work properly.');
    }
  }
  
  // 记录请求
  logRequest(url, options) {
    if (!this.config.enableRequestLogging) return;
    
    const logEntry = {
      url: url,
      method: options.method || 'GET',
      timestamp: Date.now(),
      userAgent: navigator.userAgent,
      referrer: document.referrer
    };
    
    this.requestHistory.push(logEntry);
    
    // 保持日志在合理范围内
    if (this.requestHistory.length > 1000) {
      this.requestHistory.shift();
    }
  }
  
  // 处理请求错误
  handleRequestError(url, options, error) {
    const errorEntry = {
      url: url,
      method: options.method || 'GET',
      error: error.message,
      timestamp: Date.now()
    };
    
    this.blockedRequests.push(errorEntry);
    
    // 触发错误事件
    const customEvent = new CustomEvent('secure-communication-error', {
      detail: errorEntry
    });
    document.dispatchEvent(customEvent);
    
    console.error('🛡️ Secure Communication Error:', errorEntry);
  }
  
  // 获取通信统计
  getCommunicationStats() {
    return {
      totalRequests: this.requestHistory.length,
      blockedRequests: this.blockedRequests.length,
      rateLimitedDomains: this.rateLimitData.size,
      recentRequests: this.requestHistory.slice(-10),
      recentBlocked: this.blockedRequests.slice(-10)
    };
  }
  
  // 获取状态
  getStatus() {
    return {
      httpsEnabled: this.config.enableHTTPS,
      certificatePinningEnabled: this.config.enableCertificatePinning,
      requestSigningEnabled: this.config.enableRequestSigning,
      responseValidationEnabled: this.config.enableResponseValidation,
      rateLimitingEnabled: this.config.enableRateLimiting,
      csrfProtectionEnabled: this.config.enableCSRFProtection,
      stats: this.getCommunicationStats(),
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.requestHistory = [];
    this.rateLimitData.clear();
    this.blockedRequests = [];
    this.trustedCertificates.clear();
  }
}

9. 依赖安全扫描

9.1 依赖安全扫描器

// 依赖安全扫描器
class DependencySecurityScanner {
  constructor(config = {}) {
    this.config = {
      enableRealTimeScanning: true,
      enableVulnerabilityDatabase: true,
      enableLicenseCheck: true,
      enableOutdatedCheck: true,
      scanInterval: 3600000, // 1小时
      vulnerabilityApiUrl: 'https://api.security-scanner.com/vulnerabilities',
      allowedLicenses: ['MIT', 'Apache-2.0', 'BSD-3-Clause', 'ISC'],
      blockedPackages: [],
      ...config
    };
    
    this.vulnerabilities = [];
    this.dependencies = new Map();
    this.scanResults = [];
    this.licenseViolations = [];
    
    this.init();
  }
  
  // 初始化
  init() {
    this.scanCurrentDependencies();
    this.setupPeriodicScanning();
    this.setupRealTimeMonitoring();
  }
  
  // 扫描当前依赖
  async scanCurrentDependencies() {
    try {
      // 获取当前加载的脚本
      const scripts = document.querySelectorAll('script[src]');
      
      for (const script of scripts) {
        await this.analyzeScript(script.src);
      }
      
      // 扫描动态导入的模块
      this.monitorDynamicImports();
      
      // 生成扫描报告
      this.generateScanReport();
    } catch (error) {
      console.error('Dependency scan failed:', error);
    }
  }
  
  // 分析脚本
  async analyzeScript(src) {
    try {
      const dependency = this.parseDependencyInfo(src);
      
      if (dependency) {
        this.dependencies.set(dependency.name, dependency);
        
        // 检查漏洞
        await this.checkVulnerabilities(dependency);
        
        // 检查许可证
        await this.checkLicense(dependency);
        
        // 检查是否过时
        await this.checkOutdated(dependency);
        
        // 检查是否被阻止
        this.checkBlocked(dependency);
      }
    } catch (error) {
      console.error('Script analysis failed:', src, error);
    }
  }
  
  // 解析依赖信息
  parseDependencyInfo(src) {
    try {
      const url = new URL(src, window.location.href);
      
      // 检查是否为CDN链接
      const cdnPatterns = [
        {
          pattern: /\/\/cdn\.jsdelivr\.net\/npm\/([^@\/]+)@([^\/]+)/,
          nameIndex: 1,
          versionIndex: 2
        },
        {
          pattern: /\/\/unpkg\.com\/([^@\/]+)@([^\/]+)/,
          nameIndex: 1,
          versionIndex: 2
        },
        {
          pattern: /\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/([^\/]+)\/([^\/]+)/,
          nameIndex: 1,
          versionIndex: 2
        }
      ];
      
      for (const { pattern, nameIndex, versionIndex } of cdnPatterns) {
        const match = src.match(pattern);
        if (match) {
          return {
            name: match[nameIndex],
            version: match[versionIndex],
            source: 'cdn',
            url: src,
            loadTime: Date.now()
          };
        }
      }
      
      // 本地脚本
      if (url.origin === window.location.origin) {
        const pathParts = url.pathname.split('/');
        const filename = pathParts[pathParts.length - 1];
        
        return {
          name: filename.replace(/\.(js|min\.js)$/, ''),
          version: 'unknown',
          source: 'local',
          url: src,
          loadTime: Date.now()
        };
      }
      
      return null;
    } catch (error) {
      console.error('Failed to parse dependency info:', src, error);
      return null;
    }
  }
  
  // 检查漏洞
  async checkVulnerabilities(dependency) {
    if (!this.config.enableVulnerabilityDatabase) return;
    
    try {
      // 模拟漏洞数据库查询
      const vulnerabilityData = await this.queryVulnerabilityDatabase(dependency);
      
      if (vulnerabilityData && vulnerabilityData.vulnerabilities.length > 0) {
        vulnerabilityData.vulnerabilities.forEach(vuln => {
          this.vulnerabilities.push({
            dependency: dependency.name,
            version: dependency.version,
            vulnerability: vuln,
            severity: vuln.severity,
            discoveredAt: Date.now()
          });
        });
        
        console.warn(`🚨 Vulnerabilities found in ${dependency.name}@${dependency.version}:`, vulnerabilityData.vulnerabilities);
      }
    } catch (error) {
      console.error('Vulnerability check failed:', dependency.name, error);
    }
  }
  
  // 查询漏洞数据库
  async queryVulnerabilityDatabase(dependency) {
    // 模拟漏洞数据库查询
    // 实际应用中会调用真实的漏洞数据库API
    
    const knownVulnerabilities = {
      'jquery': {
        '1.0.0': [{
          id: 'CVE-2020-11022',
          severity: 'medium',
          description: 'XSS vulnerability in jQuery',
          fixedIn: '3.5.0'
        }],
        '2.0.0': [{
          id: 'CVE-2020-11023',
          severity: 'medium',
          description: 'XSS vulnerability in jQuery',
          fixedIn: '3.5.0'
        }]
      },
      'lodash': {
        '4.17.15': [{
          id: 'CVE-2021-23337',
          severity: 'high',
          description: 'Prototype pollution vulnerability',
          fixedIn: '4.17.21'
        }]
      }
    };
    
    const packageVulns = knownVulnerabilities[dependency.name];
    if (packageVulns && packageVulns[dependency.version]) {
      return {
        vulnerabilities: packageVulns[dependency.version]
      };
    }
    
    return { vulnerabilities: [] };
  }
  
  // 检查许可证
  async checkLicense(dependency) {
    if (!this.config.enableLicenseCheck) return;
    
    try {
      const licenseInfo = await this.getLicenseInfo(dependency);
      
      if (licenseInfo && !this.config.allowedLicenses.includes(licenseInfo.license)) {
        this.licenseViolations.push({
          dependency: dependency.name,
          version: dependency.version,
          license: licenseInfo.license,
          discoveredAt: Date.now()
        });
        
        console.warn(`⚖️ License violation: ${dependency.name}@${dependency.version} uses ${licenseInfo.license}`);
      }
    } catch (error) {
      console.error('License check failed:', dependency.name, error);
    }
  }
  
  // 获取许可证信息
  async getLicenseInfo(dependency) {
    // 模拟许可证信息查询
    const knownLicenses = {
      'jquery': 'MIT',
      'lodash': 'MIT',
      'react': 'MIT',
      'vue': 'MIT',
      'angular': 'MIT'
    };
    
    const license = knownLicenses[dependency.name] || 'Unknown';
    
    return {
      license: license,
      url: `https://opensource.org/licenses/${license}`
    };
  }
  
  // 检查是否过时
  async checkOutdated(dependency) {
    if (!this.config.enableOutdatedCheck) return;
    
    try {
      const latestVersion = await this.getLatestVersion(dependency);
      
      if (latestVersion && this.isVersionOutdated(dependency.version, latestVersion)) {
        console.info(`📦 Outdated dependency: ${dependency.name}@${dependency.version} (latest: ${latestVersion})`);
      }
    } catch (error) {
      console.error('Outdated check failed:', dependency.name, error);
    }
  }
  
  // 获取最新版本
  async getLatestVersion(dependency) {
    // 模拟版本查询
    const latestVersions = {
      'jquery': '3.6.0',
      'lodash': '4.17.21',
      'react': '18.2.0',
      'vue': '3.2.45',
      'angular': '15.0.0'
    };
    
    return latestVersions[dependency.name] || null;
  }
  
  // 检查版本是否过时
  isVersionOutdated(currentVersion, latestVersion) {
    // 简单的版本比较(实际应用中应使用更复杂的版本比较逻辑)
    const current = currentVersion.split('.').map(Number);
    const latest = latestVersion.split('.').map(Number);
    
    for (let i = 0; i < Math.max(current.length, latest.length); i++) {
      const currentPart = current[i] || 0;
      const latestPart = latest[i] || 0;
      
      if (currentPart < latestPart) {
        return true;
      } else if (currentPart > latestPart) {
        return false;
      }
    }
    
    return false;
  }
  
  // 检查是否被阻止
  checkBlocked(dependency) {
    if (this.config.blockedPackages.includes(dependency.name)) {
      console.error(`🚫 Blocked dependency detected: ${dependency.name}`);
      
      // 触发阻止事件
      const event = new CustomEvent('dependency-blocked', {
        detail: dependency
      });
      document.dispatchEvent(event);
    }
  }
  
  // 监控动态导入
  monitorDynamicImports() {
    // 拦截动态import
    const originalImport = window.import || (() => {});
    
    if (typeof originalImport === 'function') {
      window.import = async (specifier) => {
        console.log('Dynamic import detected:', specifier);
        
        // 分析动态导入的模块
        if (typeof specifier === 'string') {
          await this.analyzeScript(specifier);
        }
        
        return originalImport(specifier);
      };
    }
  }
  
  // 设置定期扫描
  setupPeriodicScanning() {
    setInterval(() => {
      this.scanCurrentDependencies();
    }, this.config.scanInterval);
  }
  
  // 设置实时监控
  setupRealTimeMonitoring() {
    if (!this.config.enableRealTimeScanning) return;
    
    // 监控新脚本的添加
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        mutation.addedNodes.forEach((node) => {
          if (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'SCRIPT' && node.src) {
            this.analyzeScript(node.src);
          }
        });
      });
    });
    
    observer.observe(document.head, {
      childList: true,
      subtree: true
    });
  }
  
  // 生成扫描报告
  generateScanReport() {
    const report = {
      timestamp: Date.now(),
      totalDependencies: this.dependencies.size,
      vulnerabilities: this.vulnerabilities.length,
      licenseViolations: this.licenseViolations.length,
      dependencies: Array.from(this.dependencies.values()),
      vulnerabilityDetails: this.vulnerabilities,
      licenseViolationDetails: this.licenseViolations,
      summary: {
        highSeverityVulns: this.vulnerabilities.filter(v => v.severity === 'high').length,
        mediumSeverityVulns: this.vulnerabilities.filter(v => v.severity === 'medium').length,
        lowSeverityVulns: this.vulnerabilities.filter(v => v.severity === 'low').length
      }
    };
    
    this.scanResults.push(report);
    
    // 保持报告在合理范围内
    if (this.scanResults.length > 10) {
      this.scanResults.shift();
    }
    
    console.log('🔍 Dependency scan completed:', report.summary);
    
    return report;
  }
  
  // 获取扫描统计
  getScanStats() {
    const latestReport = this.scanResults[this.scanResults.length - 1];
    
    return {
      totalScans: this.scanResults.length,
      latestScan: latestReport ? latestReport.timestamp : null,
      totalDependencies: this.dependencies.size,
      totalVulnerabilities: this.vulnerabilities.length,
      totalLicenseViolations: this.licenseViolations.length,
      summary: latestReport ? latestReport.summary : null
    };
  }
  
  // 获取状态
  getStatus() {
    return {
      realTimeScanningEnabled: this.config.enableRealTimeScanning,
      vulnerabilityDatabaseEnabled: this.config.enableVulnerabilityDatabase,
      licenseCheckEnabled: this.config.enableLicenseCheck,
      outdatedCheckEnabled: this.config.enableOutdatedCheck,
      stats: this.getScanStats(),
      config: this.config
    };
  }
  
  // 清理
  cleanup() {
    this.vulnerabilities = [];
    this.dependencies.clear();
    this.scanResults = [];
    this.licenseViolations = [];
  }
}

10. 最佳实践与总结

10.1 安全防护架构设计原则

1. 深度防御策略
// 多层安全防护管理器
class LayeredSecurityManager {
  constructor() {
    this.layers = {
      frontend: new FrontendSecurityManager(),
      xss: new XSSProtection(),
      csrf: new CSRFProtection(),
      clickjacking: new ClickjackingProtection(),
      csp: new ContentSecurityPolicyManager(),
      input: new InputValidationManager(),
      storage: new SecureStorageManager(),
      communication: new SecureCommunicationManager(),
      dependency: new DependencySecurityScanner()
    };
    
    this.init();
  }
  
  init() {
    // 初始化所有安全层
    Object.values(this.layers).forEach(layer => {
      if (layer.init && typeof layer.init === 'function') {
        layer.init();
      }
    });
    
    // 设置层间协调
    this.setupLayerCoordination();
  }
  
  setupLayerCoordination() {
    // 安全事件协调
    document.addEventListener('security-threat-detected', (event) => {
      this.handleSecurityThreat(event.detail);
    });
  }
  
  handleSecurityThreat(threat) {
    console.warn('🚨 Security threat detected:', threat);
    
    // 根据威胁类型采取相应措施
    switch (threat.type) {
      case 'xss':
        this.layers.xss.handleThreat(threat);
        break;
      case 'csrf':
        this.layers.csrf.handleThreat(threat);
        break;
      case 'clickjacking':
        this.layers.clickjacking.handleThreat(threat);
        break;
      default:
        this.layers.frontend.handleThreat(threat);
    }
  }
  
  getSecurityStatus() {
    const status = {};
    
    Object.entries(this.layers).forEach(([name, layer]) => {
      if (layer.getStatus && typeof layer.getStatus === 'function') {
        status[name] = layer.getStatus();
      }
    });
    
    return status;
  }
}
2. 性能优化策略
  • 异步处理: 安全检查不阻塞主线程
  • 缓存机制: 缓存验证结果和安全策略
  • 批量处理: 批量处理安全事件
  • 懒加载: 按需加载安全模块
3. 监控与告警
  • 实时监控: 监控安全事件和威胁
  • 日志记录: 详细记录安全相关操作
  • 告警机制: 及时通知安全威胁
  • 统计分析: 分析安全趋势和模式

10.2 开发团队最佳实践

1. 安全开发流程
  • 安全需求分析: 在项目初期识别安全需求
  • 威胁建模: 分析潜在的安全威胁
  • 安全编码: 遵循安全编码规范
  • 安全测试: 进行全面的安全测试
  • 安全审计: 定期进行安全审计
2. 代码审查要点
  • 输入验证: 检查所有用户输入的验证
  • 输出编码: 确保输出内容正确编码
  • 权限控制: 验证权限控制逻辑
  • 敏感数据: 检查敏感数据处理
  • 第三方依赖: 审查第三方库的安全性
3. 安全培训计划
  • 基础安全知识: OWASP Top 10等
  • 前端安全特点: XSS、CSRF等前端特有威胁
  • 安全工具使用: 安全扫描和测试工具
  • 应急响应: 安全事件处理流程

10.3 技术选型建议

1. 框架选择
  • React: 内置XSS防护,但需注意dangerouslySetInnerHTML
  • Vue: 模板系统提供基础防护
  • Angular: 内置安全机制,如DomSanitizer
2. 工具推荐
  • ESLint Security Plugin: 静态代码安全检查
  • Snyk: 依赖漏洞扫描
  • OWASP ZAP: Web应用安全测试
  • Content Security Policy: 内容安全策略

10.4 未来发展趋势

1. AI驱动的安全防护
  • 智能威胁检测: 使用机器学习检测异常行为
  • 自适应防护: 根据威胁情况自动调整防护策略
  • 预测性安全: 预测潜在的安全威胁
2. 零信任架构
  • 持续验证: 持续验证用户和设备
  • 最小权限: 最小化访问权限
  • 微分段: 网络和应用微分段
3. 隐私保护增强
  • 数据最小化: 只收集必要的数据
  • 本地处理: 在客户端处理敏感数据
  • 加密传输: 端到端加密通信

10.5 核心价值与收益

1. 业务价值
  • 用户信任: 提升用户对产品的信任度
  • 合规要求: 满足法律法规要求
  • 品牌保护: 避免安全事件对品牌的损害
  • 成本节约: 预防安全事件的成本远低于事后处理
2. 技术收益
  • 系统稳定性: 提高系统的稳定性和可靠性
  • 开发效率: 标准化的安全组件提高开发效率
  • 维护成本: 降低安全维护成本
  • 技术债务: 减少安全相关的技术债务

结语

前端安全防护是一个复杂而重要的技术领域,需要从多个维度进行综合考虑。本文提供的完整解决方案涵盖了XSS、CSRF、点击劫持、CSP、输入验证、安全存储、安全通信和依赖安全等关键方面。

通过实施这些安全措施,可以显著提升Web应用的安全性,保护用户数据和隐私。同时,建立完善的安全开发流程和监控体系,能够持续改进安全防护能力。

在实际项目中,应根据具体需求和风险评估,选择合适的安全策略和技术方案。安全防护是一个持续的过程,需要不断学习新的威胁和防护技术,保持安全防护能力的先进性。


网站公告

今日签到

点亮在社区的每一天
去签到