Skip to content

Handle CSP security requirements on <script> tags and specify default_headers config #279

@philayres

Description

@philayres

CSP Implementation Plan

Overview

Enable Content-Security-Policy header with nonce-based script/style protection, starting in report-only mode to identify issues before enforcement.


Phase 1: Configure CSP Infrastructure

1.1 Enable CSP Configuration

File: config/initializers/content_security_policy.rb

Uncomment and configure:

Rails.application.config.content_security_policy do |policy|
  policy.default_src :self, :https
  policy.font_src    :self, :https, :data
  policy.img_src     :self, :https, :data
  policy.object_src  :none
  policy.script_src  :self, :https
  policy.style_src   :self, :https
  policy.report_uri  "/csp-violation-report-endpoint"
end

# Start in report-only mode
Rails.application.config.content_security_policy_report_only = true

1.2 Configure Nonce Generator

Rails.application.config.content_security_policy_nonce_generator = ->(request) { 
  SecureRandom.base64(16) 
}

Rails.application.config.content_security_policy_nonce_directives = %w[script-src style-src]

1.3 Create Violation Report Endpoint

Create controller to log CSP violations for monitoring:

# app/controllers/csp_reports_controller.rb
class CspReportsController < ApplicationController
  skip_before_action :verify_authenticity_token
  
  def create
    Rails.logger.warn("CSP Violation: #{request.body.read}")
    head :no_content
  end
end

Add route: post '/csp-violation-report-endpoint', to: 'csp_reports#create'


Phase 2: Add Nonces to Layouts

2.1 Main Layout - app/views/layouts/application.html.erb

Add csp_meta_tag to head:

<%= csp_meta_tag %>

Convert inline scripts (lines 24-35, 40-41, 57-59) to use javascript_tag nonce: true and style_tag nonce: true.

2.2 Setup App Partial - app/views/layouts/_setup_app.html.erb

Wrap entire content in javascript_tag nonce: true.

2.3 Admin Layout - app/views/layouts/admin_application.html.erb

Convert inline <script> tags to javascript_tag nonce: true.

2.4 Other Layouts

File Change
layouts/child_error_reporter.html.erb Wrap in javascript_tag nonce: true
layouts/_force_window_home.html.erb Wrap in javascript_tag nonce: true
layouts/nfs_store/filestore.html.erb Wrap in javascript_tag nonce: true

Phase 3: Handle Handlebars Templates

The <script type="text/x-handlebars-template"> tags don't execute JavaScript - they're data containers. Test in report-only mode to confirm they don't trigger violations.


Phase 4: Testing & Enforcement

4.1 Deploy in Report-Only Mode

  • Monitor /csp-violation-report-endpoint logs
  • Fix any violations found

4.2 Switch to Enforcement

Rails.application.config.content_security_policy_report_only = false

Files to Modify

File Change
config/initializers/content_security_policy.rb Configure CSP + nonces
config/routes.rb Add violation report route
app/controllers/csp_reports_controller.rb Create new controller
app/views/layouts/application.html.erb 4 inline scripts → javascript_tag
app/views/layouts/_setup_app.html.erb 1 large script → javascript_tag
app/views/layouts/admin_application.html.erb 2 inline scripts → javascript_tag
app/views/layouts/child_error_reporter.html.erb 1 inline script
app/views/layouts/_force_window_home.html.erb 1 inline script
app/views/layouts/nfs_store/filestore.html.erb 1 inline script
public/502.html Static file - outside app scope

Out of Scope

  • zeus_short_link.rb generates HTML with inline script for S3-hosted redirects - runs outside Rails app's CSP headers
  • public/502.html - static error page served by web server, not Rails

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestsecuritySecurity issue or CVE in dependency

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions