diff --git a/CHANGELOG.md b/CHANGELOG.md index 62367f74..07efc9b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## Unreleased + +- [FIX] Add CSP nonce support to flamegraph rendering [#648](https://github.com/MiniProfiler/rack-mini-profiler/pull/648) + ## 4.0.1 - 2025-07-31 - [FIX] Ensure Rack 2 / 3 cross compatibility [#653](https://github.com/MiniProfiler/rack-mini-profiler/pull/653) diff --git a/lib/mini_profiler/views.rb b/lib/mini_profiler/views.rb index 87566881..96100931 100644 --- a/lib/mini_profiler/views.rb +++ b/lib/mini_profiler/views.rb @@ -10,6 +10,18 @@ def share_template @share_template ||= ERB.new(::File.read(::File.expand_path("../html/share.html", ::File.dirname(__FILE__)))) end + def get_csp_nonce(env, response_headers = {}) + configured_nonce = @config.content_security_policy_nonce + if configured_nonce && !configured_nonce.is_a?(String) + configured_nonce = configured_nonce.call(env, response_headers) + end + + configured_nonce || + env["action_dispatch.content_security_policy_nonce"] || + env["secure_headers_content_security_policy_nonce"] || + "" + end + def generate_html(page_struct, env, result_json = page_struct.to_json) # double-assigning to suppress "assigned but unused variable" warnings path = path = "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}" @@ -39,15 +51,6 @@ def get_profile_script(env, response_headers = {}) url = "#{path}includes.js?v=#{version}" if !url css_url = "#{path}includes.css?v=#{version}" if !css_url - configured_nonce = @config.content_security_policy_nonce - if configured_nonce && !configured_nonce.is_a?(String) - configured_nonce = configured_nonce.call(env, response_headers) - end - - content_security_policy_nonce = configured_nonce || - env["action_dispatch.content_security_policy_nonce"] || - env["secure_headers_content_security_policy_nonce"] - settings = { path: path, url: url, @@ -66,7 +69,7 @@ def get_profile_script(env, response_headers = {}) collapseResults: @config.collapse_results, htmlContainer: @config.html_container, hiddenCustomFields: @config.snapshot_hidden_custom_fields.join(','), - cspNonce: content_security_policy_nonce, + cspNonce: get_csp_nonce(env, response_headers), hotwireTurboDriveSupport: @config.enable_hotwire_turbo_drive_support, } @@ -112,6 +115,8 @@ def make_link(postfix, env) def flamegraph(graph, path, env) headers = { 'content-type' => 'text/html' } iframe_src = "#{public_base_path(env)}speedscope/index.html" + csp_nonce = get_csp_nonce(env, headers) + html = <<~HTML @@ -123,7 +128,7 @@ def flamegraph(graph, path, env) -