--- description: How to configure Content Security Policy in Ruby on Rails with the content_security_policy DSL, nonces and report-only mode. --- # Ruby on Rails Rails has shipped a CSP DSL for years, and it is one of the more pleasant implementations: the policy is Ruby rather than a string, nonces are wired in through a configurable generator, and report-only is a single boolean. ## What Rails gives you - A `content_security_policy` block in an initializer, with a method per directive. - Per-controller overrides, so a policy can be tightened or relaxed on specific actions without duplicating the whole thing. - `config.content_security_policy_nonce_generator`, a lambda that receives the request and returns the nonce. - The `csp_meta_tag` helper for exposing the nonce to JavaScript in your layout. - `config.content_security_policy_report_only` to switch the whole policy to the report-only header. ## Setting the header Define the policy in `config/initializers/content_security_policy.rb`. Your URL comes from the [Setup](https://report-uri.com/account/setup/) page: ```ruby 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.report_uri "https://abc123.report-uri.com/r/d/csp/reportOnly" end Rails.application.config.content_security_policy_report_only = true ``` Flip `content_security_policy_report_only` to `false` when you are ready to enforce, and point `report_uri` at the `enforce` endpoint at the same time. ## Adding a nonce ```ruby config.content_security_policy_nonce_generator = ->(request) { SecureRandom.base64(16) } ``` Add `csp_meta_tag` to your layout's ``, and Rails will attach the nonce to tags generated by `javascript_tag` and friends. ## Things to watch for - A nonce generator keyed off something stable - the session ID is the usual mistake - is not a nonce. Use `SecureRandom` per request. - Per-controller overrides replace rather than merge in some cases; check the resulting header rather than assuming, especially where an override sits on a parent controller. - `report_uri` takes the raw URL. It does not need quoting, unlike the source expressions. ## Official documentation [Ruby on Rails - Securing Rails Applications: Content Security Policy](https://guides.rubyonrails.org/security.html) ## Start Monitoring with Report URI **Already using us for CSP?** Find your report-uri value on [Setup](https://report-uri.com/account/setup/), or view your [CSP reports](https://report-uri.com/account/reports/csp/). **New to Report URI?** Create an account and grab your report-uri value from the [Setup](https://report-uri.com/account/setup/) page. [Start your free trial](https://report-uri.com/register/?plan=starter2025)