Ruby on Rails 5.2からContent Security Policyヘッダーを設定するDSLが提供されました。
2.5 Content Security Policy
Rails 5.2 ships with a new DSL that allows you to configure a Content Security Policy for your application. You can configure a global default policy and then override it on a per-resource basis and even use lambdas to inject per-request values into the header such as account subdomains in a multi-tenant application. You can read more about this in the Securing Rails Applications guide.
Ruby on Rails 5.2 Release Notes — Ruby on Rails Guides
今更ながら個人のサービスに適用してみたので使い方とかをメモ📝
Content Security Policyとは?
HTTP の Content-Security-Policy レスポンスヘッダーは、ウェブサイト管理者が、あるページにユーザーエージェントが読み込みを許可されたリソースを管理できるようにします。いくつかの例外を除いて、大半のポリシーにはサーバーオリジンとスクリプトエンドポイントの指定を含んでいます。これはクロスサイトスクリプティング攻撃 (クロスサイトスクリプティング) を防ぐのに役立ちます。 Content-Security-Policy - HTTP | MDN
上述の通りレンスポンスヘッダーでクライアントがロードするリソースの許可条件を設定できる機能ようです。
CSP を有効にするには、ウェブサーバーから Content-Security-Policy HTTP ヘッダーを返すように設定する必要があります 他にも、 要素を用いてポリシーを指定することも可能です。例を挙げます。 コンテンツセキュリティポリシー (CSP) - HTTP | MDN
設定するにはHTTPヘッダーまたはmetaタグでポリシーに記述することで行えます。
# HTTPヘッダーでContent-Security-Policyを返すようにする Content-Security-Policy: default-src 'self' # or metaタグを設定する <meta http-equiv="Content-Security-Policy" content="default-src 'self' />
Ruby on RailsでContent Security Policyを設定する
Ruby on RailsではDSLを使ってContent-Security-Policy HTTP ヘッダーの内容及びCSP関連の振る舞いを指定することができます。
Rails.application.configure do config.content_security_policy do |policy| policy.default_src :self, :https # 同一オリジン OR httpsで取得するリソースのみ許可 policy.script_src :strict_dynamic # nonceにより検証が成功したリソースのみを許可 end # Generate session nonces for permitted importmap and inline scripts config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } # session_idをnonceの取得元として使用する config.content_security_policy_nonce_directives = %w[script-src] # JavaScriptはnonceによる検証の対象にする # Report CSP violations to a specified URI. See: # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only config.content_security_policy_report_only = true # CSP違反があってもエラーとしない end
※cssのstrict_dynamic
にしたい場合にはpolicy.style_src :strict_dynamic
にし、content_security_policy_nonce_directives = %w[script-src style-src]
を指定するようにすれば良い。
※ Viteを利用している場合には制約上、script_src: unsafe-eval
, style_src: unsafe-inline
を許可する必要がある(?)ようです Link
nonce
の付与はjavascript_include_tag
等であればnonce: true
を指定すれば自動的に付与できますが、
script
タグを直接記載しているときにはcontent_security_policy_nonce
でnonce
を取得することもできるので直接指定することもできます。
<script nonce="<%= content_security_policy_nonce %>">
おわりに
Ruby on Rails、こういうのを簡単に指定できて非常に便利ですね 🚃