{"version":3,"file":"csp-manager.mjs","sources":["../../../src/lib/security/csp-manager.ts"],"sourcesContent":["/**\n * @fileoverview Content Security Policy Manager\n * @module @/lib/security/csp-manager\n *\n * Comprehensive CSP management for the Harbor React Framework.\n * Provides nonce generation, dynamic policy building, violation reporting,\n * and integration with React for inline script/style handling.\n *\n * @see https://www.w3.org/TR/CSP3/\n * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP\n *\n * @author Harbor Security Team\n * @version 1.0.0\n */\n\nimport type {\n  CSPDirective,\n  CSPManagerConfig,\n  CSPNonce,\n  CSPNonceValue,\n  CSPPolicy,\n  CSPSourceValue,\n  CSPViolationHandler,\n  CSPViolationReport,\n} from './types';\nimport { cspConfig, SECURITY_TIMING } from '@/config/security.config';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Nonce entropy in bytes (256 bits)\n */\nconst NONCE_ENTROPY_BYTES = 32;\n\n/**\n * Maximum number of violations to store\n */\nconst MAX_VIOLATIONS_STORED = 100;\n\n/**\n * Debounce time for violation reports in milliseconds\n */\nconst { VIOLATION_REPORT_DEBOUNCE } = SECURITY_TIMING;\n\n// ============================================================================\n// Cryptographic Utilities\n// ============================================================================\n\n/**\n * Generate cryptographically secure random bytes\n * Uses Web Crypto API for security\n */\nfunction getRandomBytes(length: number): Uint8Array {\n  const bytes = new Uint8Array(length);\n  crypto.getRandomValues(bytes);\n  return bytes;\n}\n\n/**\n * Convert bytes to base64 string\n */\nfunction bytesToBase64(bytes: Uint8Array): string {\n  const binString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join('');\n  return btoa(binString);\n}\n\n/**\n * Generate a cryptographically secure nonce\n * @returns Base64-encoded nonce string\n */\nfunction generateNonceValue(): string {\n  const bytes = getRandomBytes(NONCE_ENTROPY_BYTES);\n  return bytesToBase64(bytes);\n}\n\n// ============================================================================\n// CSP Manager Class\n// ============================================================================\n\n/**\n * CSP Manager for handling Content Security Policy\n *\n * Features:\n * - Cryptographically secure nonce generation\n * - Dynamic policy building with nonce injection\n * - CSP violation monitoring and reporting\n * - Support for report-only mode\n * - Automatic nonce rotation\n *\n * @example\n * ```typescript\n * const cspManager = CSPManager.getInstance();\n *\n * // Get current nonce for inline scripts\n * const nonce = cspManager.getCurrentNonce();\n *\n * // Build CSP header value\n * const cspHeader = cspManager.buildPolicyString();\n *\n * // Add violation handler\n * cspManager.addViolationHandler((violation) => {\n *   console.error('CSP Violation:', violation);\n * });\n * ```\n */\nclass CSPManagerClass {\n  private static instance: CSPManagerClass | null = null;\n\n  private config: CSPManagerConfig;\n  private currentNonce: CSPNonce | null = null;\n  private violations: CSPViolationReport[] = [];\n  private violationHandlers: Set<CSPViolationHandler> = new Set();\n  private reportDebounceTimer: ReturnType<typeof setTimeout> | null = null;\n  private pendingReports: CSPViolationReport[] = [];\n  private initialized = false;\n\n  private constructor(config: CSPManagerConfig = cspConfig) {\n    this.config = { ...config };\n\n    // Add configured handlers\n    config.violationHandlers.forEach((handler) => {\n      this.violationHandlers.add(handler);\n    });\n  }\n\n  /**\n   * Get singleton instance of CSP Manager\n   */\n  static getInstance(config?: CSPManagerConfig): CSPManagerClass {\n    CSPManagerClass.instance ??= new CSPManagerClass(config);\n    return CSPManagerClass.instance;\n  }\n\n  /**\n   * Reset singleton instance (for testing)\n   */\n  static resetInstance(): void {\n    if (CSPManagerClass.instance) {\n      CSPManagerClass.instance.cleanup();\n      CSPManagerClass.instance = null;\n    }\n  }\n\n  // ==========================================================================\n  // Initialization\n  // ==========================================================================\n\n  /**\n   * Initialize the CSP Manager\n   * Sets up violation reporting listener\n   */\n  initialize(): void {\n    if (this.initialized) {\n      return;\n    }\n\n    // Generate initial nonce\n    if (this.config.enableNonces) {\n      this.regenerateNonce();\n    }\n\n    // Set up violation reporting\n    if (this.config.reportViolations) {\n      this.setupViolationListener();\n    }\n\n    this.initialized = true;\n  }\n\n  /**\n   * Cleanup resources\n   */\n  cleanup(): void {\n    if (this.reportDebounceTimer) {\n      clearTimeout(this.reportDebounceTimer);\n      this.reportDebounceTimer = null;\n    }\n\n    // Remove violation listener\n    if (typeof document !== 'undefined') {\n      document.removeEventListener('securitypolicyviolation', this.handleViolationEvent);\n    }\n\n    this.violations = [];\n    this.pendingReports = [];\n    this.violationHandlers.clear();\n    this.initialized = false;\n  }\n\n  // ==========================================================================\n  // Nonce Management\n  // ==========================================================================\n\n  /**\n   * Generate a new nonce\n   * @returns The generated nonce object\n   */\n  regenerateNonce(): CSPNonce {\n    const nonce: CSPNonce = {\n      value: generateNonceValue(),\n      generatedAt: Date.now(),\n      ttl: this.config.nonceTtl,\n      used: false,\n    };\n\n    this.currentNonce = nonce;\n    return nonce;\n  }\n\n  /**\n   * Get the current nonce value\n   * Regenerates if expired\n   * @returns Current nonce value as branded type\n   */\n  getCurrentNonce(): CSPNonceValue {\n    if (!this.config.enableNonces) {\n      throw new Error('Nonces are not enabled in CSP configuration');\n    }\n\n    // Check if nonce exists and is not expired\n    if (this.currentNonce) {\n      const age = Date.now() - this.currentNonce.generatedAt;\n      if (age < this.currentNonce.ttl) {\n        return this.currentNonce.value as CSPNonceValue;\n      }\n    }\n\n    // Regenerate expired or missing nonce\n    const nonce = this.regenerateNonce();\n    return nonce.value as CSPNonceValue;\n  }\n\n  /**\n   * Get nonce attribute string for inline scripts\n   * @returns Nonce attribute for use in script tags\n   */\n  getScriptNonceAttr(): string {\n    const nonce = this.getCurrentNonce();\n    return `nonce=\"${nonce}\"`;\n  }\n\n  /**\n   * Get nonce attribute string for inline styles\n   * @returns Nonce attribute for use in style tags\n   */\n  getStyleNonceAttr(): string {\n    const nonce = this.getCurrentNonce();\n    return `nonce=\"${nonce}\"`;\n  }\n\n  /**\n   * Mark current nonce as used\n   * For tracking nonce usage\n   */\n  markNonceUsed(): void {\n    if (this.currentNonce) {\n      this.currentNonce.used = true;\n    }\n  }\n\n  /**\n   * Check if nonce is still valid\n   */\n  isNonceValid(): boolean {\n    if (!this.currentNonce) {\n      return false;\n    }\n    const age = Date.now() - this.currentNonce.generatedAt;\n    return age < this.currentNonce.ttl;\n  }\n\n  // ==========================================================================\n  // Policy Building\n  // ==========================================================================\n\n  /**\n   * Build the complete CSP policy object\n   * Injects nonces into script-src and style-src directives\n   * @returns Complete CSP policy\n   */\n  buildPolicy(): CSPPolicy {\n    const policy: CSPPolicy = { ...this.config.basePolicy };\n\n    // Inject nonce into script and style directives\n    if (this.config.enableNonces) {\n      const nonceValue = `'nonce-${this.getCurrentNonce()}'`;\n\n      // Script directives\n      const scriptSrc = policy['script-src'] ?? [\"'self'\"];\n      policy['script-src'] = [...scriptSrc, nonceValue];\n\n      const scriptSrcElem = policy['script-src-elem'];\n      if (scriptSrcElem) {\n        policy['script-src-elem'] = [...scriptSrcElem, nonceValue];\n      }\n\n      // Style directives\n      const styleSrc = policy['style-src'] ?? [\"'self'\"];\n      policy['style-src'] = [...styleSrc, nonceValue];\n\n      const styleSrcElem = policy['style-src-elem'];\n      if (styleSrcElem) {\n        policy['style-src-elem'] = [...styleSrcElem, nonceValue];\n      }\n    }\n\n    // Add report-uri if configured\n    if (this.config.reportUri != null && this.config.reportUri !== '') {\n      policy['report-uri'] = [this.config.reportUri];\n    }\n\n    return policy;\n  }\n\n  /**\n   * Build CSP header string from policy\n   * @returns CSP header value string\n   */\n  buildPolicyString(): string {\n    const policy = this.buildPolicy();\n    const directives: string[] = [];\n\n    for (const [directive, values] of Object.entries(policy)) {\n      if (values != null && values.length > 0) {\n        // Some directives don't have values (e.g., upgrade-insecure-requests)\n        const valueStr = values.length > 0 && values[0] !== '' ? ` ${values.join(' ')}` : '';\n        directives.push(`${directive}${valueStr}`);\n      } else if (values != null) {\n        // Directive without values (boolean-like)\n        directives.push(directive);\n      }\n    }\n\n    return directives.join('; ');\n  }\n\n  /**\n   * Get the appropriate CSP header name\n   * @returns Header name based on report-only setting\n   */\n  getHeaderName(): string {\n    return this.config.reportOnly\n      ? 'Content-Security-Policy-Report-Only'\n      : 'Content-Security-Policy';\n  }\n\n  /**\n   * Add a source to a directive\n   * @param directive - The CSP directive\n   * @param source - The source value to add\n   */\n  addSource(directive: CSPDirective, source: CSPSourceValue): void {\n    const currentSources = this.config.basePolicy[directive] ?? [];\n    if (!currentSources.includes(source)) {\n      this.config = {\n        ...this.config,\n        basePolicy: {\n          ...this.config.basePolicy,\n          [directive]: [...currentSources, source],\n        },\n      };\n    }\n  }\n\n  /**\n   * Remove a source from a directive\n   * @param directive - The CSP directive\n   * @param source - The source value to remove\n   */\n  removeSource(directive: CSPDirective, source: CSPSourceValue): void {\n    const currentSources = this.config.basePolicy[directive];\n    if (currentSources) {\n      this.config = {\n        ...this.config,\n        basePolicy: {\n          ...this.config.basePolicy,\n          [directive]: currentSources.filter((s) => s !== source),\n        },\n      };\n    }\n  }\n\n  // ==========================================================================\n  // Violation Reporting\n  // ==========================================================================\n\n  /**\n   * Record a CSP violation\n   * @param violation - The violation report\n   */\n  recordViolation(violation: CSPViolationReport): void {\n    // Add to stored violations\n    this.violations.push(violation);\n\n    // Trim if exceeds max\n    while (this.violations.length > MAX_VIOLATIONS_STORED) {\n      this.violations.shift();\n    }\n\n    // Notify handlers\n    this.violationHandlers.forEach((handler) => {\n      try {\n        handler(violation);\n      } catch (error) {\n        console.error('[CSP] Violation handler error:', error);\n      }\n    });\n\n    // Queue for reporting\n    if (this.config.reportUri != null && this.config.reportUri !== '') {\n      this.queueViolationReport(violation);\n    }\n  }\n\n  /**\n   * Add a violation handler\n   * @param handler - The handler function\n   * @returns Cleanup function to remove handler\n   */\n  addViolationHandler(handler: CSPViolationHandler): () => void {\n    this.violationHandlers.add(handler);\n    return () => this.violationHandlers.delete(handler);\n  }\n\n  /**\n   * Remove a violation handler\n   * @param handler - The handler to remove\n   */\n  removeViolationHandler(handler: CSPViolationHandler): void {\n    this.violationHandlers.delete(handler);\n  }\n\n  /**\n   * Get recorded violations\n   * @returns Array of recorded violations\n   */\n  getViolations(): readonly CSPViolationReport[] {\n    return [...this.violations];\n  }\n\n  /**\n   * Clear recorded violations\n   */\n  clearViolations(): void {\n    this.violations = [];\n  }\n\n  /**\n   * Create a meta tag element with CSP\n   * For client-side CSP enforcement\n   * @returns HTMLMetaElement with CSP policy\n   */\n  createMetaTag(): HTMLMetaElement {\n    const meta = document.createElement('meta');\n    meta.httpEquiv = this.config.reportOnly\n      ? 'Content-Security-Policy-Report-Only'\n      : 'Content-Security-Policy';\n    meta.content = this.buildPolicyString();\n    return meta;\n  }\n\n  /**\n   * Inject CSP meta tag into document head\n   * Note: Meta tag CSP is less effective than HTTP header\n   */\n  injectMetaTag(): void {\n    if (typeof document === 'undefined') {\n      return;\n    }\n\n    // Remove existing CSP meta tags\n    const existingMetas = document.querySelectorAll(\n      'meta[http-equiv=\"Content-Security-Policy\"], meta[http-equiv=\"Content-Security-Policy-Report-Only\"]'\n    );\n    existingMetas.forEach((meta) => meta.remove());\n\n    // Inject new meta tag\n    const meta = this.createMetaTag();\n    document.head.insertBefore(meta, document.head.firstChild);\n  }\n\n  /**\n   * Get current configuration\n   */\n  getConfig(): Readonly<CSPManagerConfig> {\n    return { ...this.config };\n  }\n\n  /**\n   * Update configuration\n   * @param updates - Partial configuration updates\n   */\n  updateConfig(updates: Partial<CSPManagerConfig>): void {\n    this.config = {\n      ...this.config,\n      ...updates,\n      // Merge base policy if provided\n      basePolicy: updates.basePolicy\n        ? { ...this.config.basePolicy, ...updates.basePolicy }\n        : this.config.basePolicy,\n    };\n  }\n\n  // ==========================================================================\n  // Meta Tag Injection\n  // ==========================================================================\n\n  /**\n   * Check if CSP Manager is initialized\n   */\n  isInitialized(): boolean {\n    return this.initialized;\n  }\n\n  /**\n   * Set up listener for CSP violation events\n   */\n  private setupViolationListener(): void {\n    if (typeof document === 'undefined') {\n      return;\n    }\n\n    document.addEventListener('securitypolicyviolation', this.handleViolationEvent);\n  }\n\n  // ==========================================================================\n  // Configuration\n  // ==========================================================================\n\n  /**\n   * Handle CSP violation event from browser\n   */\n  private handleViolationEvent = (event: SecurityPolicyViolationEvent): void => {\n    const violation: CSPViolationReport = {\n      documentUri: event.documentURI,\n      referrer: event.referrer,\n      blockedUri: event.blockedURI,\n      violatedDirective: event.violatedDirective,\n      effectiveDirective: event.effectiveDirective,\n      originalPolicy: event.originalPolicy,\n      disposition: event.disposition as 'enforce' | 'report',\n      statusCode: event.statusCode,\n      lineNumber: event.lineNumber || undefined,\n      columnNumber: event.columnNumber || undefined,\n      sourceFile: event.sourceFile || undefined,\n      sample: event.sample || undefined,\n    };\n\n    this.recordViolation(violation);\n  };\n\n  /**\n   * Queue violation for debounced reporting\n   */\n  private queueViolationReport(violation: CSPViolationReport): void {\n    this.pendingReports.push(violation);\n\n    // Clear existing timer\n    if (this.reportDebounceTimer) {\n      clearTimeout(this.reportDebounceTimer);\n    }\n\n    // Set up debounced report\n    this.reportDebounceTimer = setTimeout(() => {\n      void this.flushViolationReports();\n    }, VIOLATION_REPORT_DEBOUNCE);\n  }\n\n  /**\n   * Flush pending violation reports to server\n   *\n   * Note: This method intentionally uses raw fetch() rather than apiClient because:\n   * 1. CSP reports have special Content-Type (application/csp-report)\n   * 2. Security reporting must be independent of the main API client\n   * 3. Uses keepalive for reliability when page is unloading\n   *\n   * @see {@link @/lib/api/api-client} for application API calls\n   */\n  private async flushViolationReports(): Promise<void> {\n    if (\n      this.pendingReports.length === 0 ||\n      this.config.reportUri == null ||\n      this.config.reportUri === ''\n    ) {\n      return;\n    }\n\n    const reports = [...this.pendingReports];\n    this.pendingReports = [];\n\n    try {\n      // Raw fetch is intentional - CSP reports require special Content-Type\n      await fetch(this.config.reportUri, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/csp-report',\n        },\n        body: JSON.stringify({\n          'csp-reports': reports,\n        }),\n        // Don't fail silently - we want to know if reporting fails\n        keepalive: true,\n      });\n    } catch (error) {\n      console.error('[CSP] Failed to report violations:', error);\n      // Re-queue failed reports (with limit to prevent infinite growth)\n      if (this.pendingReports.length < MAX_VIOLATIONS_STORED) {\n        this.pendingReports.push(...reports);\n      }\n    }\n  }\n}\n\n// ============================================================================\n// Singleton Export\n// ============================================================================\n\n/**\n * CSP Manager singleton instance\n */\nexport const CSPManager = CSPManagerClass.getInstance();\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate a new cryptographic nonce\n * Standalone function for one-off nonce generation\n */\nexport function generateNonce(): CSPNonceValue {\n  return generateNonceValue() as CSPNonceValue;\n}\n\n/**\n * Parse a CSP header string into policy object\n * @param cspString - The CSP header value\n * @returns Parsed CSP policy object\n */\nexport function parseCSPString(cspString: string): CSPPolicy {\n  const policy: CSPPolicy = {};\n\n  const directives = cspString.split(';').map((d) => d.trim());\n\n  for (const directive of directives) {\n    if (!directive) continue;\n\n    const parts = directive.split(/\\s+/);\n    const name = parts[0] as CSPDirective;\n    const values = parts.slice(1);\n\n    policy[name] = values.length > 0 ? values : [];\n  }\n\n  return policy;\n}\n\n/**\n * Merge multiple CSP policies\n * Later policies take precedence for conflicting directives\n * @param policies - Array of policies to merge\n * @returns Merged policy\n */\nexport function mergeCSPPolicies(...policies: CSPPolicy[]): CSPPolicy {\n  const merged: CSPPolicy = {};\n\n  for (const policy of policies) {\n    for (const [directive, values] of Object.entries(policy)) {\n      const key = directive as CSPDirective;\n      const existing = merged[key] ?? [];\n      const newValues = values ?? [];\n\n      // Deduplicate values\n\n      merged[key] = [...new Set([...existing, ...newValues])];\n    }\n  }\n\n  return merged;\n}\n\n/**\n * Create a strict CSP policy for high-security contexts\n * @returns Strict CSP policy\n */\nexport function createStrictPolicy(): CSPPolicy {\n  return {\n    'default-src': [\"'none'\"],\n    'script-src': [\"'self'\"],\n    'style-src': [\"'self'\"],\n    'img-src': [\"'self'\"],\n    'font-src': [\"'self'\"],\n    'connect-src': [\"'self'\"],\n    'media-src': [\"'none'\"],\n    'object-src': [\"'none'\"],\n    'frame-src': [\"'none'\"],\n    'frame-ancestors': [\"'none'\"],\n    'form-action': [\"'self'\"],\n    'base-uri': [\"'self'\"],\n    'upgrade-insecure-requests': [],\n    'block-all-mixed-content': [],\n  };\n}\n\n/**\n * Validate that a CSP policy doesn't contain dangerous values\n * @param policy - The policy to validate\n * @returns Validation result with warnings\n */\nexport function validateCSPPolicy(policy: CSPPolicy): {\n  isSecure: boolean;\n  warnings: string[];\n} {\n  const warnings: string[] = [];\n\n  const dangerousValues = [\n    { value: \"'unsafe-inline'\", message: 'unsafe-inline allows XSS attacks' },\n    { value: \"'unsafe-eval'\", message: 'unsafe-eval allows code injection' },\n    { value: '*', message: 'Wildcard allows any source' },\n    { value: 'data:', message: 'data: URLs can bypass CSP' },\n  ];\n\n  const criticalDirectives = ['script-src', 'script-src-elem', 'object-src', 'base-uri'];\n\n  for (const directive of criticalDirectives) {\n    const values = policy[directive as CSPDirective];\n    if (!values) continue;\n\n    for (const { value, message } of dangerousValues) {\n      if (values.includes(value)) {\n        warnings.push(`${directive}: ${message}`);\n      }\n    }\n  }\n\n  // Check for missing default-src\n  if (!policy['default-src']) {\n    warnings.push('Missing default-src directive - recommend setting to \"\\'none\\'\" or \"\\'self\\'\"');\n  }\n\n  // Check for missing object-src\n  if (!policy['object-src']) {\n    warnings.push('Missing object-src directive - recommend setting to \"\\'none\\'\"');\n  }\n\n  return {\n    isSecure: warnings.length === 0,\n    warnings,\n  };\n}\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type { CSPManagerClass };\nexport type {\n  CSPPolicy,\n  CSPDirective,\n  CSPSourceValue,\n  CSPNonce,\n  CSPManagerConfig,\n  CSPViolationReport,\n  CSPViolationHandler,\n  CSPNonceValue,\n};\n"],"names":["NONCE_ENTROPY_BYTES","MAX_VIOLATIONS_STORED","VIOLATION_REPORT_DEBOUNCE","SECURITY_TIMING","getRandomBytes","length","bytes","bytesToBase64","binString","byte","generateNonceValue","CSPManagerClass","config","cspConfig","handler","nonce","policy","nonceValue","scriptSrc","scriptSrcElem","styleSrc","styleSrcElem","directives","directive","values","valueStr","source","currentSources","s","violation","error","meta","updates","event","reports","CSPManager","generateNonce","parseCSPString","cspString","d","parts","name","mergeCSPPolicies","policies","merged","key","existing","newValues","createStrictPolicy","validateCSPPolicy","warnings","dangerousValues","criticalDirectives","value","message"],"mappings":"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"}