Skip to content
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

Content Security Policy error because of inline script #3816

Closed
jezdez opened this issue May 21, 2019 · 8 comments · Fixed by #3832
Closed

Content Security Policy error because of inline script #3816

jezdez opened this issue May 21, 2019 · 8 comments · Fixed by #3832
Labels

Comments

@jezdez
Copy link
Member

jezdez commented May 21, 2019

Issue Summary

@ranbena @arikfr The change in #3609 leads to a Content Security Policy error when loading any page:

Chrome:

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

Firefox:

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”).

I don't think we should add unsafe-inline to the script-src directive but instead indeed provide a per-request nonce in the format

<script nonce="<random nonce>">
    //...
</script>

Flask-Talisman supports rendering a random nonce like shown in the example here . Sadly we can't just not apply CSP since the templates are used on every page, if I understand correctly.

Right now multi_org.html is the only one that is rendered via Jinja2, but I think it's safe to do that for index.html, right?

Alternatively, would it suffice to move the <script> block into an own script that we can load instead?

Can you think of a way to fix this?

Steps to Reproduce

  1. Open any page.
  2. See the browser console.

Technical details:

  • Redash Version: master
  • Browser/OS: Firefox/macOS
  • How did you install Redash: Docker
@arikfr
Copy link
Member

arikfr commented May 21, 2019

Both options are not great:

  • Rendering with Jinja -> couples the frontend with the backend, which we want to avoid.
  • Moving this script to its own file -> makes page load slower.

What if we move it to its own file, but also move it to the body section? @ranbena

@jezdez jezdez changed the title Content Security Policy because of inline script Content Security Policy error because of inline script May 21, 2019
@jezdez
Copy link
Member Author

jezdez commented May 21, 2019

(sorry for the typos)

@ranbena
Copy link
Contributor

ranbena commented May 21, 2019

What if we move it to its own file, but also move it to the body section? @ranbena

Relocating the script into body won't improve perf. Scripts are synchronous by default no matter where in the document they are declared.

Options:

  1. We can generate the nonce (a hash of the script content) and use it hardcoded to avoid relying on a server. I don't see us changing this script anytime soon so it might be good enough.
  2. We can explicitly set async on the script for optimal loading perf but then we won't be able to use the IE conditional comment (it expects onIE() to already exist). I think this can be worked around with more useragent parsing.
  3. We can explicitly set defer on the script, so it loads after document is ready but it may not run if previous scripts generate an error, which is expected if browser is IE. I'm not certain of this though.

Looks like option 2 is best.

@arikfr
Copy link
Member

arikfr commented May 22, 2019

We can generate the nonce (a hash of the script content) and use it hardcoded to avoid relying on a server. I don't see us changing this script anytime soon so it might be good enough.

The nonce should be randomized on every request or otherwise it serves no purpose :)

Is there some good reference on why having script tags is a security concern?

@ranbena
Copy link
Contributor

ranbena commented May 22, 2019

The nonce should be randomized on every request or otherwise it serves no purpose :)

Got the terms mixed up. I meant "hash-source" <hash-algorithm>-<base64-value>.

Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='

More info here

Is there some good reference on why having script tags is a security concern?

I reckon it has to do with the risk of 3rd party modification like browser extensions.

@arikfr
Copy link
Member

arikfr commented May 26, 2019

The hash-source option seems as the best one, no?

@ranbena
Copy link
Contributor

ranbena commented May 26, 2019

The hash-source option seems as the best one, no?

Apparently, his feature (SRI) is only available for external file fetches.

I'll attempt the 2nd option then.

@jezdez
Copy link
Member Author

jezdez commented May 28, 2019

Thanks @ranbena!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants