Safeguard
Security Guides•

How do you roll out a Content Security Policy in Rails safely?

Start a Rails Content Security Policy in report-only mode, collect violations, fix them, then enforce. Steps, nonces and per-controller overrides.

Safeguard Security Team
4 min read

Define the policy in the Rails initializer, turn on report-only mode first, collect violation reports, fix the legitimate ones, then enforce it once reports go quiet. Rails supports this with content_security_policy_report_only, so a policy can be tested on real traffic without breaking pages.

What a CSP is

A Content Security Policy is a response header that tells the browser which sources of scripts, styles, images and other content are allowed on a page. The Rails security guide recommends defining one to help protect against XSS and injection attacks, and provides a DSL for it in config/initializers/content_security_policy.rb.

It limits the damage if an injection bug exists. It does not replace output escaping.

A starting policy

The guide's example sets the default source to self and https, allows fonts and images from self, https and data, sets object sources to none, and limits scripts and styles to self and https. It also sets a report_uri for violations.

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

The rollout

PhaseSettingGoal
1. Observecontent_security_policy_report_only = trueSee what would break
2. FixRemove inline scripts, add needed sourcesReduce violations
3. EnforceRemove report-onlyBlock violations
4. MaintainKeep reporting onCatch regressions

The guide describes report-only mode for exactly this case, migrating legacy content. In that mode the browser sends the Content-Security-Policy-Report-Only header and reports violations without blocking.

Rails.application.config.content_security_policy_report_only = true

You can also set report-only on a single controller, which is handy when you want to tighten one area at a time.

Steps

  1. Inventory where scripts and styles come from: your assets, a CDN, analytics, payment widgets.
  2. Write the first policy and turn on report-only.
  3. Build an endpoint to receive reports, or use a reporting service, and review them for a week or two.
  4. Move inline scripts into files. Where you cannot, use nonces.
  5. Add only the third party sources you actually need.
  6. Enforce, first on a low traffic path.
  7. Keep the report endpoint live afterward.

Nonces and overrides

If you are tempted to allow unsafe-inline, the guide says to consider nonces, which give a per-request token to scripts you trust. Rails also lets you override the global policy per controller, disable it for one action with content_security_policy false, only: :index, and use lambdas for per request values in multi tenant apps. Use the disable switch sparingly, and note why.

Common pitfalls

  • Browser extensions generate noise in reports. Filter, do not panic.
  • Admin and legacy pages are often the last to be fixed. Give them a dated plan.
  • A wide https: source permits any HTTPS host, which is weaker than listing hosts. Tighten over time.

Who owns it

A policy decays when nobody owns it. Name an owner, put the policy file in code review, and require a note when someone adds a new source. Review the report endpoint once a month, because new third party scripts arrive quietly through tag managers and marketing requests.

Quick check

Will report-only block anything?

No. It sends the report-only header, so the browser reports violations but allows the content.

Does a CSP replace escaping?

No. It is a second layer for when escaping fails.

Safeguard's policy gates can help enforce release checks for security headers in your pipeline. A free scan is at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.