跳至主要内容
搜索工具
主题

仅保存在此设备上。

中文

Content Security Policy Fixes

Summary

Fixed the main CSP violations reported in the browser console. The policy is currently in report-only mode, so violations are logged but don't block functionality.

Changes Made (2026-05-22)

1. Development Tools WebSocket Support ✅

Problem: Browser Link (port 50133) and Hot Reload (port 65291) WebSocket connections were blocked by connect-src 'self'.

Fix: Updated SecurityHeadersMiddleware.cs to detect development mode and allow WebSocket connections to localhost:* in development:

if (isDevelopment)
{
    builder.Append("connect-src 'self' ws://localhost:* http://localhost:*; ");
}
else
{
    builder.Append("connect-src 'self'; ");
}

Impact: Browser Link and Hot Reload now work without CSP violations in development.


2. upgrade-insecure-requests Warning ✅

Problem: The directive upgrade-insecure-requests is ignored in report-only mode and causes console warnings.

Fix: Only include upgrade-insecure-requests when CSP is in enforcing mode:

if (options.Enforce)
{
    builder.Append("upgrade-insecure-requests");
}

Impact: Console warning eliminated in report-only mode.


3. Font Loading Inline Handler ✅

Problem: _MaterialSymbolsFont.cshtml used onload="this.onload=null;this.rel='stylesheet'" which violates CSP.

Fix: Replaced inline handler with nonce'd script:

<link rel="preload" ... id="material-symbols-preload" />
<script nonce="...">
  (function() {
    var link = document.getElementById('material-symbols-preload');
    if (link) {
      link.onload = null;
      link.rel = 'stylesheet';
    }
  })();
</script>

Impact: Font loading is now CSP-compliant.


4. Inline Event Handlers - Complete Refactoring ✅

Problem: 26 inline event handlers across 8 files violated CSP when 'strict-dynamic' is active.

Files Fixed:

  • Areas/Admin/Views/Analytics/Index.cshtml (1 handler: onsubmit)
  • Areas/Admin/Views/Seo/Workflows.cshtml (1 handler: onclick)
  • Areas/Admin/Views/Seo/BulkOperations.cshtml (12 handlers: onclick)
  • Areas/Admin/Views/EeatContent/FactChecks.cshtml (1 handler: onclick)
  • Areas/Admin/Views/EeatContent/QualityScores.cshtml (1 handler: onclick)
  • Areas/Admin/Views/EeatContent/ContentFreshness.cshtml (2 handlers: onclick)
  • Areas/Admin/Views/EeatContent/ExpertVerifications.cshtml (2 handlers: onclick)
  • Areas/Admin/Views/SocialDistribution/CreatePost.cshtml (6 handlers: onchange, oninput, onclick)

Fix: Replaced all inline handlers with CSP-compliant event delegation:

  1. Replaced inline onclick, onchange, oninput, onsubmit with data-action attributes
  2. Added event delegation using document.addEventListener with nonce'd scripts
  3. Used data-* attributes to pass parameters instead of inline function calls

Example Refactoring:

<!-- Before -->
<button onclick="showModal('123', 'Test')">Open</button>

<!-- After -->
<button data-action="show-modal" data-id="123" data-title="Test">Open</button>

<script nonce="@Context.Items["csp-nonce"]">
  document.addEventListener('click', function(e) {
    if (e.target.closest('[data-action="show-modal"]')) {
      var button = e.target.closest('[data-action="show-modal"]');
      showModal(button.dataset.id, button.dataset.title);
    }
  });
</script>

Impact: All inline event handlers eliminated. Zero CSP violations for event handlers.


Remaining Work

None - All Known CSP Violations Fixed ✅

All inline event handlers have been refactored to use CSP-compliant event delegation. The application is now ready for CSP enforcement mode.

Previous Remaining Work (Now Completed)

Inline Event Handlers (40+ occurrences across 19 files)

Problem: Many views use inline event handlers (onclick, onchange, etc.) which violate CSP when 'strict-dynamic' is active in modern browsers.

Files affected:

  • Areas/Admin/Views/EeatContent/*.cshtml (6 files, 8 handlers)
  • Areas/Admin/Views/ProgrammaticSeo/*.cshtml (3 files, 5 handlers)
  • Areas/Admin/Views/Seo/*.cshtml (2 files, 14 handlers)
  • Areas/Admin/Views/SocialDistribution/*.cshtml (3 files, 8 handlers)
  • Areas/Admin/Views/ToolCreationStudio/*.cshtml (2 files, 2 handlers)
  • Areas/Admin/Views/GeoAeo/Index.cshtml (1 handler)
  • Areas/Admin/Views/SeoMonitoring/Alerts.cshtml (1 handler)
  • Areas/User/Views/Vault/Index.cshtml (1 handler)
  • Views/Shared/_AuthLayout.cshtml (1 handler)

Solution approaches:

  1. Gradual migration (recommended):

    • Keep CSP in report-only mode
    • Refactor pages one at a time
    • Move inline handlers to external event listeners
    • Test each page after refactoring
  2. Quick fix (temporary):

    • Remove 'strict-dynamic' from CSP temporarily
    • This allows inline handlers to work
    • Gives time for proper refactoring
  3. Automated refactoring:

    • Create a shared event delegation system
    • Use data attributes instead of inline handlers
    • Example: data-action="confirm-delete" instead of onclick="return confirm(...)"

Example Refactoring

Before:

<button onclick="showModal(123, 'Test')">Open</button>

After:

<button data-action="show-modal" data-id="123" data-title="Test">Open</button>

<script nonce="...">
  document.addEventListener('click', function(e) {
    if (e.target.dataset.action === 'show-modal') {
      showModal(e.target.dataset.id, e.target.dataset.title);
    }
  });
</script>

Current CSP Policy

default-src 'self';
script-src 'self' 'nonce-{random}' 'strict-dynamic' 'unsafe-inline' https: http:;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: blob: https:;
font-src 'self' https://fonts.gstatic.com data:;
connect-src 'self' [ws://localhost:* http://localhost:* in dev];
frame-src 'self' blob:;
frame-ancestors 'none';
object-src 'none';
base-uri 'self';
form-action 'self';
[upgrade-insecure-requests when enforcing]

Key points:

  • 'strict-dynamic' means modern browsers ignore 'self' and host allowlists for scripts
  • 'unsafe-inline' is kept for backwards compatibility but ignored when nonce is present
  • Policy is in report-only mode by default (SecurityHeaders:ContentSecurityPolicy:Enforce: false)

Next Steps

  1. Test the current fixes: Verify Browser Link and Hot Reload work without console errors
  2. Plan inline handler migration: Prioritize high-traffic pages first
  3. Consider enforcement timeline: When to flip Enforce: true in configuration
  4. Monitor violations: Use browser console to track remaining issues

Configuration

To enforce CSP (block violations instead of just reporting):

{
  "SecurityHeaders": {
    "ContentSecurityPolicy": {
      "Enforce": true
    }
  }
}

Warning: Don't enable enforcement until all inline handlers are fixed, or functionality will break in modern browsers.