---
title: "Rails 5.2 DSL for configuring Content Security Policy"
description: "Rails 5.2 adds DSL for configuring Content Security Policy header"
canonical_url: "https://www.bigbinary.com/blog/rails-5-2-adds-dsl-for-configuring-content-security-policy-header"
markdown_url: "https://www.bigbinary.com/blog/rails-5-2-adds-dsl-for-configuring-content-security-policy-header.md"
---

# Rails 5.2 DSL for configuring Content Security Policy

Rails 5.2 adds DSL for configuring Content Security Policy header

- Author: Sushant Mittal
- Published: October 23, 2018
- Categories: Rails 5.2, Rails

Content Security Policy (CSP) is an added layer of security that helps to detect
and mitigate various types of attacks on our web applications, including Cross
Site Scripting (XSS) and data injection attacks.

## What is XSS ?

In this attack, victim's browser may execute malicious scripts because browser
trusts the source of the content even when it's not coming from the correct
source.

[Here is](https://blog.bigbinary.com/2012/05/10/xss-and-rails.html) our blog on
XSS written sometime back.

## How CSP can be used to mitigate and report this attack ?

By using CSP, we can specify domains that are valid sources of executable
scripts. Then a browser with CSP compatibility will only execute those scripts
that are loaded from these whitelisted domains.

Please note that CSP makes XSS attack a lot harder but CSP does not make XSS
attack impossible. CSP does not stop DOM-based XSS (also known as client-side
XSS). To prevent DOM-based XSS, Javascript code should be carefully written to
avoid introducing such vulnerabilities.

In Rails 5.2, [a DSL was added](https://github.com/rails/rails/pull/31162) for
configuring Content Security Policy header.

## Let's check the configuration.

We can define global policy for the project in an initializer.

```ruby

# config/initializers/content_security_policy.rb

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, :unsafe_inline
policy.report_uri "/csp-violation-report-endpoint"
end
```

We can override global policy within a controller as well.

```ruby

# Override policy inline

class PostsController < ApplicationController
content_security_policy do |policy|
policy.upgrade_insecure_requests true
end
end
```

```ruby

# Using mixed static and dynamic values

class PostsController < ApplicationController
content_security_policy do |policy|
policy.base_uri :self, -> { "https://#{current_user.domain}.example.com" }
end
end
```

## Content Security Policy can be deployed in report-only mode as well.

Here is global setting in an initializer.

```ruby

# config/initializers/content_security_policy.rb

Rails.application.config.content_security_policy_report_only = true
```

Here we are putting an override at controller level.

```ruby
class PostsController < ApplicationController
content_security_policy_report_only only: :index
end
```

Policy specified in `content_security_policy_report_only` header will not be
enforced, but any violations will be reported to a provided URI. We can provide
this violation report URI in `report_uri` option.

```ruby

# config/initializers/content_security_policy.rb

Rails.application.config.content_security_policy do |policy|
policy.report_uri "/csp-violation-report-endpoint"
end
```

If both `content_security_policy_report_only` and `content_security_policy`
headers are present in the same response then policy specified in
`content_security_policy` header will be enforced while
`content_security_policy_report_only` policy will generate reports but will not
be enforced.

## Links

- [Human page](https://www.bigbinary.com/blog/rails-5-2-adds-dsl-for-configuring-content-security-policy-header)
