8

I'm trying to implement stripe payment system in Django. For adding card payments, I followed the guide in this link. After adding HTML markup in Django template and CSS and JS code as separate static files, I got the following console error in Firefox:

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

What I understand from above error message is that, <script src="https://js.stripe.com/v3/"></script> JS file contains links to other JS files and Firefox blocks such connections. It should be noted that, at this stage test credit card payment is working as expected and amount debited by client is added to my stripe account's test balance. To address this blocking problem, I followed the instructions in this link. As such, I added following meta tag to my Django template:

<meta http-equiv="Content-Security-Policy" content="connect-src https://api.stripe.com; frame-src https://js.stripe.com https://hooks.stripe.com; script-src https://js.stripe.com" />

After adding above Content-Security-Policy directives, Firefox console no longer shows aforementioned blocking errors, but this time my static JS files are blocked. I have modified directives as below for allowing my JS files (added 'self' to 'script-src' directive):

<meta http-equiv="Content-Security-Policy" content="connect-src https://api.stripe.com; frame-src https://js.stripe.com https://hooks.stripe.com; script-src 'self' https://js.stripe.com" />

And this time before mentioned inline-script block error reappeared in Firefox console. :)

Can you help me for this issue? Is my understanding correct regarding the cause of Firefox console error? Why implemented solution is not working?

EDIT

Can it be simply Firefox bug, considering that payment is working as expected and Chromium browser does not log any error on developer tools?

Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
Elgin Cahangirov
  • 1,932
  • 4
  • 24
  • 45
  • 1
    Not a direct answer, but consider trying [Django-CSP](https://github.com/mozilla/django-csp) by Monzilla. You might have more luck and it was easier (for me) to configure my CSP. – bones225 Sep 28 '19 at 21:23
  • @bones225 I looked at that plugin. But I don't want to use third party plugins for such "small" problems and always try to avoid using them as much as possible. – Elgin Cahangirov Sep 28 '19 at 21:59
  • @ElginCahangirov I couldn't agree more, however, after writing the answer to your question, I have seriously reconsidered using that package... – Lord Elrond Sep 29 '19 at 04:54
  • 1
    @ElginCahangirov I get where you are coming from. For me I'd consider the Monzilla package to be _almost_ essential for Django apps. I like to keep Django security settings exclusively in `settings.py`. I guess an exception would be if different pages need different CSPs. – bones225 Sep 29 '19 at 20:52

3 Answers3

5

According to Mozilla's docs on Content-Security-Policy, there are tons of other security policies, and if your js/css files require one of those to be set, they will be blocked.

Luckily, there is an easy fix, default-src. From the aforementioned docs:

The HTTP Content-Security-Policy (CSP) default-src directive serves as a fallback for the other CSP fetch directives. For each of the following directives that are absent, the user agent will look for the default-src directive and will use this value for it:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; ...

Note that default-src only applies to fetch directives, so you may need to add a few policies that your page requires.

Also, you will need to specify self for each policy that you define, because firefox will only look to the default-src when a required policy is null.

So if you have a policy like this:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src http://example.com;">

You will exclude yourself from the script-src policy, but you should be covered by all the other policies, with the exception of the policies that look to script-src as a backup before looking to default-src (eg script-src-elem).

Unfortunately, this also extends to all dependencies that your script has, such as bootstrap or jQuery. each dependency will need to be explicitly referenced in each policy that they require.

If only someone had a package to simplify this process...

Lastly, this answer was an excellent resource for learning about Content-Security-Policy.

Edit

To give you the exact Content-Security-Policy that your page requires, I would need to see the error messages you received. That being said, here is a guess, given the information I have (with line breaks for readability):

<meta http-equiv="Content-Security-Policy" content="
default-src 'self'; 
connect-src 'self' https://api.stripe.com; 
frame-src 'self' https://js.stripe.com https://hooks.stripe.com; 
script-src 'self' https://js.stripe.com 'unsafe-inline'
"  />

You should not add line breaks to the policy in your actual code, instead write it like this:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; connect-src 'self' https://api.stripe.com; frame-src 'self' https://js.stripe.com https://hooks.stripe.com; script-src 'self' https://js.stripe.com 'unsafe-inline'"/>
Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • Thank you for your answer and the resources (`default-src` directive is a good trick). But at the end, I can't see answer to my question.Did you try implement `stripe js` and be able to get rid of above mentioned console error in Firefox browser? – Elgin Cahangirov Sep 30 '19 at 17:31
  • @ElginCahangirov I didn't setup the api itself, but I was able to recreate your problem by using your exact `Content-Security-Policy`, and was able to fix it by adding the policies that my scripts required. That being said should have made an attempt to answer your question directly (although it is difficult to do without seeing the error messages you got), so I added one in an update. – Lord Elrond Oct 03 '19 at 02:19
4

Answer to this question is Redux DevTools Firefox extension. After disabling this extension, console errors disappear. You can easily test this by going to this link in Firefox browser with Redux DevTools enabled. There is also an open github issue about this problem.

Elgin Cahangirov
  • 1,932
  • 4
  • 24
  • 45
1

I suggest you to use django-csp by Mozilla. It is very easy to configure and it works perfectly.

Here you can find the repo: https://github.com/mozilla/django-csp

and here the documentation: https://django-csp.readthedocs.io/en/latest/

Fabio Caccamo
  • 1,871
  • 19
  • 21