You can report CSP violations to a log file. There will be a lots of noise, that is not related to errors in your application but raised from various browser extensions of your visitors.
Add the endpoint in you CSP config/initializers/content_security_policy.rb:
Rails.application.configure do
config.content_security_policy do |policy|
# Settings for the policy
policy.report_uri '/content_security_policy_report'
end
end
Create a controller app/controllers/content_security_policy_reports_controller.rb to write the reports to a log file:
class ContentSecurityPolicyReportsController < ApplicationController
skip_forgery_protection
def create
if request.content_type == 'application/csp-report'
Rails.logger.info("Content Security Policy Report: #{request.user_agent} #{request.body.read}")
head :ok
else
head :bad_request
end
end
end
And change your routes + add some a test:
resource :content_security_policy_report, only: :create
describe ContentSecurityPolicyReportsController do
describe 'POST /content_security_policy_report' do
before { allow(Rails.logger).to receive(:info) }
it 'returns a bad request code if the content type does not match' do
post '/content_security_policy_report'
expect(response).to have_http_status(400)
end
it 'reports the content security policy violation including the user agent to the logs' do
expect(Rails.logger).to receive(:info).with('Content Security Policy Report: Mozilla/5.0 ["test"]')
post '/content_security_policy_report', params: ['test'].to_json, headers: { 'Content-Type': 'application/csp-report', 'User-Agent': 'Mozilla/5.0' }
expect(response).to have_http_status(200)
end
end
end
Notes:
- You might want to use a different log file
- It might be a good idea to enable rate limiting Show archive.org snapshot for the controller
- You might want to use Sentry instead
Posted by Emanuel to makandra dev (2026-04-10 14:01)