brentd / xray-rails

☠️ A development tool that reveals your UI's bones
MIT License
1.22k stars 79 forks source link

Allow it to work with strict Content Security Policy; add nonce to javascript_include_tag #100

Open TylerRick opened 5 years ago

TylerRick commented 5 years ago

I've used this gem before with success, but I just tried adding it to an app that happens to have a strict CSP and am running into this error:

Refused to load the script
'http://some.dev.hostname/assets/xray.self-130d130a29b059ab5e1f6b7ea349011b67ee8593ecb3e9222db86c7a5d55ed3a.js?body=1'
because it violates the following Content Security Policy directive:
"script-src 'self' https: 'strict-dynamic' 'sha256-...'
'nonce-RNrEgMJkrdj8D2U9IljIDQ=='". 'strict-dynamic' is present, so host-based
whitelisting is disabled. Note that 'script-src-elem' was not explicitly set,
so 'script-src' is used as a fallback.

I wonder if there would be an easy fix to make it work out of the box with strict CSP. Could it be as simple as changing:

lib/xray/middleware.rb:116:

-       "#{$~}\n" + helper.javascript_include_tag(script_name)
+       "#{$~}\n" + helper.javascript_include_tag(script_name, nonce: true)

?

I don't know if that helper can access the request's nonce from within a middleware but maybe...

(Otherwise, it could always use a regex to extract the nonce from the <meta name="csp-nonce" tag.)

As a workaround, I guess I'll have to disable my strict CSP in development, but I'd prefer to keep it strict in development as well so that I ran into any CSP issues sooner...

Reference:

TylerRick commented 5 years ago

Well, adding nonce: true there didn't work. That results in:

NoMethodError - undefined method `content_security_policy_nonce' for nil:NilClass:

because it tries to delegate to controller here, and it is nil:

# actionview (5.2.3) lib/action_view/helpers/asset_tag_helper.rb
          if tag_options["nonce"] == true
            tag_options["nonce"] = content_security_policy_nonce
          end