rmosolgo / graphiql-rails

Mount the GraphiQL query editor in a Rails app
MIT License
447 stars 135 forks source link

Content Security Policy issue #46

Closed jejacks0n closed 6 years ago

jejacks0n commented 6 years ago

I've actually not seen this kind of issue before, and I'm unsure how it's happening and what the implications are at a higher level, but it's keeping things from loading.

I've a very basic and simple implementation at the moment, and am just starting out with the graphql toolset.

I start the rails server in the development environment (default) and browse to the mounted engine at graphiql and see "Loading..." in the DOM and the following in the console:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' https: 'unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-OncdEJD4oqeHhZYWbJ3+w14Ptu8kMNYBli6LjYjVZRs='), or a nonce ('nonce-...') is required to enable inline execution.

It seems like the problem stems from the opening script tag. I'm using Rails 5.2.1.

Here's some more reading: https://developers.google.com/web/fundamentals/security/csp/

jejacks0n commented 6 years ago

I had adjusted the config/content_security_policy.rb and disallowed inline script tags. I had to adjust the enable them in development.

Here's more or less what I ended up with in case anybody else ends up in this same place since it's actually a recommended step when setting up webpacker and vue with rails.

Rails.application.config.content_security_policy do |policy|
  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval, :unsafe_inline
  else
    policy.script_src :self, :https
  end
end
philiplambok commented 5 years ago

Thank you @jejacks0n

sambostock commented 2 years ago

I'm investigating addressing the root cause of needing 'unsafe-eval' in the CSP, but I want to share an alternative workaround for the time being:

if defined?(GraphiQL::Rails)
  # While the gem is loaded up front, its controller is autoloaded.
  # Therefore we must ensure our patch runs after loading, every time.
  Rails.autoloaders.main.on_load("GraphiQL::Rails::EditorsController") do
    GraphiQL::Rails::EditorsController.content_security_policy do |policy|
      policy.script_src(*policy.script_src, :unsafe_eval)
    end
  end
end

Rather than add 'unsafe-eval' to the entire host app's CSP, this only adds it to the relevant controller.

If for some reason it is impossible to address the unsafely eval'ing JS in GraphiQL itself (e.g. new Function("return this;")), then we can update this gem to do the controller level CSP change itself, but ideally we'll fix it upstream.