Construct Content Security Policy from multiple files

Right now, the Content Security Policy lives in one file. This can grow to be pretty big, especially if you’re using multiple services that provide things like embeds. I’ve developed a gem, Zantetsuken, to slice this up. The idea is that instead of using one initializer for your entire CSP, you use a file per library or feature that you’re using. You can see an example of what a ruleset for your CSP might look like on the README. Files of this nature are combined together, and this configuration is passed to ActionDispatch::ContentSecurityPolicy to build the CSP for the app.

As a whole, it’s very much inspired by what’s been done to break down routes.

In its current v0.1.0 form, it’s not perfect, for a few reasons:

  • I’m having to manually require app/lib/zantetsuken in the initializer. It’d be nice to autoload this folder or do whatever the draw solution for routes does.
  • The ruleset files themselves are Ruby classes, which might be better off replaced with a complete DSL such as:
# config/ruleset/stripe/js.rb
# Ruleset for Stripe's JS library.
ruleset do
  connect_src 'https://api.stripe.com'
  frame_src 'https://js.stripe.com', 'https://hooks.stripe.com'
  script_src 'https://js.stripe.com'
  other_src 'https://example.com'
  # A common problem is that some rules are environment-specific.
  group :development do
    other_src 'https://example2.com'
  end
end

This is the goal I have in mind for Zantetsuken, but I was wondering if there’d be any interest in including this directly into Action Dispatch itself?

1 Like

If you absolutely need to make an exception for some legacy inline code that can’t be moved out to separate file, CSP provides two features to allow specific code blocks without resorting to unsafe-inline!