From b40c7509655294c47238af812d784425a5d62f8c Mon Sep 17 00:00:00 2001 From: Soufiane Date: Wed, 31 May 2023 15:28:16 +0200 Subject: [PATCH] Turbolinks broken by default with a secure CSP [SCI-8583] (#5529) * Fix broken Turbolinks with CSP nonce [SCI-8583] --- app/assets/javascripts/shared/turbo_link_csp.js | 10 ++++++++++ app/views/layouts/application.html.erb | 2 +- config/initializers/security_policy.rb | 11 +++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/shared/turbo_link_csp.js diff --git a/app/assets/javascripts/shared/turbo_link_csp.js b/app/assets/javascripts/shared/turbo_link_csp.js new file mode 100644 index 000000000..e9eb6d158 --- /dev/null +++ b/app/assets/javascripts/shared/turbo_link_csp.js @@ -0,0 +1,10 @@ +document.addEventListener('turbolinks:request-start', function(event) { + var xhr = event.data.xhr; + xhr.setRequestHeader('X-Turbolinks-Nonce', $('meta[name="csp-nonce"]').prop('content')); +}); + +document.addEventListener('turbolinks:before-cache', function() { + $('script[nonce]').each(function(_index, element) { + $(element).attr('nonce', element.nonce); + }); +}); diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 885612308..66c300dee 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -12,7 +12,7 @@ <% end %> <%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %> <%= stylesheet_link_tag 'application', media: 'all' %> - + <%= csp_meta_tag %> <% if ::NewRelic::Agent.instance.started? %> <%= ::NewRelic::Agent.browser_timing_header(controller.request.content_security_policy_nonce) %> <% end %> diff --git a/config/initializers/security_policy.rb b/config/initializers/security_policy.rb index 41df3da91..ad3c57d8a 100644 --- a/config/initializers/security_policy.rb +++ b/config/initializers/security_policy.rb @@ -18,8 +18,15 @@ Rails.application.config.content_security_policy do |policy| # policy.report_uri "/csp-violation-report-endpoint" end -# If you are using UJS then enable automatic nonce generation -Rails.application.config.content_security_policy_nonce_generator = ->_request { SecureRandom.base64(16) } +# https://discuss.rubyonrails.org/t/turbolinks-broken-by-default-with-a-secure-csp/74790 +Rails.application.config.content_security_policy_nonce_generator = ->(request) do + # use the same csp nonce for turbolinks requests + if request.env['HTTP_TURBOLINKS_REFERRER'].present? + request.env['HTTP_X_TURBOLINKS_NONCE'] + else + SecureRandom.base64(16) + end +end # Set the nonce only to specific directives Rails.application.config.content_security_policy_nonce_directives = %w(script-src)