-
Notifications
You must be signed in to change notification settings - Fork 4
Description
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 = true1.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
endAdd 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-endpointlogs - Fix any violations found
4.2 Switch to Enforcement
Rails.application.config.content_security_policy_report_only = falseFiles 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.rbgenerates HTML with inline script for S3-hosted redirects - runs outside Rails app's CSP headerspublic/502.html- static error page served by web server, not Rails