Skip to content
MDView as Markdown

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 page:

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

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

Add csp_meta_tag to your layout's <head>, 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

Start Monitoring with Report URI

Already using us for CSP? Find your report-uri value on Setup, or view your CSP reports.

New to Report URI? Create an account and grab your report-uri value from the Setup page.

Start your free trial