New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strict Content Security Policy breaks web-console #242
Comments
I like the way we currently inject the console, as it's quite portable. It does not depend on the asset pipeline and we can show it mostly everywhere without issues. Your case being the exception here. For sure, I would like to support it, if it's not too disruptive to what we currently have. Can you explain the second option you proposed in a bit more detail? I don't think I want to pursue either 1 or 3. |
Sure! With CSP, you can specify a nonce in your CSP header. In my policy above, this is the It means that <style nonce="devOnly">
body { background-color: red; }
</style>
<script nonce="devOnly">
console.log('I am authorized')
</script> The requirement for The same is required for javascript, From what I saw in the source code of an error page in my rails app, this is needed:
I am not familiar at all with If this is too much work (and too few benefits), the simplest implementation would be to allow the developer to configure a block that will be run when WebConsole.before_display do
# Here I can change the CSP policy for this request to allow inline JS / Style
end This is more like a workaround, but it would work for 99% of the usecases. CSP support is now in all major browsers and a lot of websites are starting to implement it with strict policies. There have been talks to include CSP support directly into Rails to improve baseline security (but probably not with a strict default policy). |
Looking at the spec, this nonce should be unique across requests, right? Secure Headers seems to set per-request nonce in a place where we can get it, so you can still set it as the That said, the above may not work, because of the way the Rails error pages are setup. The console itself is just injected on pages, the default error page is not that exceptional. Its content, however does have a couple of script tags. Now, providing a way to set those internal nonces and setting it in Rails proper may be a bit more disruptive. |
It looks like I indeed made a mistake and most of the work needs to be done on Rails error page. I thought it was generated by For the nonce, it should be unique per request in production. This is why the configuration for the nonce should accept a block, so you can dynamically provide the nonce. In my case, I am using a static nonce in development, and none in production. I am using external Hot Module Reloading via Webpacker (in dev only) and I have not found a way to share a dynamic nonce between I guess if Rails implements CSP support on the error page there will be a Rails-way to set the nonce, and you can then reuse it in |
This seems relevant again now that Rails includes a CSP middleware by default. |
I think a nonce approach might be very straightforward. Putting this out there, as it could be an easy pull request, but I don't have time to land it right now. What Rails provides: I think we can assume users would configure Rails' CSP to generate a nonce, as per the Securing Rails Applications guide. Rails provides
Looking at rails-ujs, it defines The nonce also appears to be available in What web-console needs: If a nonce is available in either the request or the "csp-nonce" meta tag, |
For those that Google brings: I worked around this with the secure-headers gem by including this in my ApplicationController: if Rails.env.development? && defined? WebConsole
rescue_from StandardError do |exception|
append_content_security_policy_directives(script_src: %w['unsafe-inline'])
raise exception
end
end |
For more informations and context about CSP: https://csp.withgoogle.com/docs/strict-csp.html
I have a quite strict CSP header on my website, using the secureheaders gem:
default-src 'self'; base-uri 'self'; block-all-mixed-content; child-src 'self' blob: localhost:8080; connect-src 'self' ws://localhost:8080 http://localhost:8080 ws://localhost:3000; font-src 'self' data: localhost:8080; form-action 'self'; frame-ancestors 'none'; img-src 'self' www.google-analytics.com data: blob: localhost:8080; object-src 'none'; script-src 'self' www.google-analytics.com localhost:8080 'nonce-devOnly' 'unsafe-eval'; style-src 'self' fonts.googleapis.com 'nonce-devOnly'
On Rails error page, the CSP header is sent and this breaks
web-console
because of inline script and style.I do not want to remove my CSP policy in development, as it allows me to catch errors that would occur in production.
I see multiple ways to fix this:
web-console
scripts and styles are moved to external files served with other Rails assets, so they are allowed by the policy (does not seem easy to do)web-console
with a nonce, and the nonce is added to the inline<script>
&<style>
tags, and all CSS is moved to<style>
tags. This is the cleaner solution, but might require quite a lot of work.secureheaders
gem is installed and web-console will be displayed, then it can callappend_content_security_policy_directives
to allow inline styles/scripts (see https://github.com/twitter/secureheaders/blob/master/docs/per_action_configuration.md). This is not ideal as it means the CSP policy is changed for this page and might no longer catch errors that would occur in production, butweb-console
should not be a permanent part of this page.This does not seem ideal to add
secureheaders
specific code inweb-console
, so this cna be implemented with a configurable callback before the console is displayed and the developer can callappend_content_security_policy_directives
from it.Any thoughts / preferences / advice?
The text was updated successfully, but these errors were encountered: