Content Security Policy: cannot load Mixpanel in C

2019-05-01 13:48发布

问题:

I've been struggling with this for the past day and there are little-to-no resources available online for integrating Chrome Extensions and Mixpanel. I'd like for this thread to by the one that people refer to when dealing with integrating Mixpanel into a Chrome extension.

The goal of my Mixpanel integration is to be able to track events both with my content script content.js as well as my popup.js (so basically across my whole extension)

I have a popup.html file that calls <script src="mixpanel.js"></script> right before the </head> tag.

In my mixpanel.js file is:

(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==
typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,
e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);

mixpanel.init("MY_TOKEN");

When I click on my extension's button and inspect it, the console outputs the following error:

Refused to load the script 'http://cdn.mxpnl.com/libs/mixpanel-2.2.min.js' because it violates the following Content Security Policy directive: "script-src 'self' https://cdn.mxpnl.com".

Here is the permissions section of my manifest.json file:

"permissions": ["https://twitter.com/"],
  "content_security_policy": "script-src 'self' https://cdn.mxpnl.com; object-src 'self'"

The extension needs to work on Twitter.

I've read the Content Security Policy doc that Google wrote which has not been helpful

Any idea what I'm doing wrong here? Any help would be very appreciated!

回答1:

The problem here is that Chrome doesn't allow extensions to load remote resources over plain HTTP; only HTTPS is allowed:

As man-in-the-middle attacks are both trivial and undetectable over HTTP, those [i.e., http:] origins will not be accepted.

Your mixpanel.js script attempts to load http://cdn.mxpnl.com/libs/mixpanel-2.2.min.js instead of the corresponding https: link. To fix this, simply change the line:

a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js'

to:

a.src='https://cdn.mxpnl.com/libs/mixpanel-2.2.min.js'

It's currently loading the http: version because window.location.protocol is chrome-extension:, rather than https:. This change simply forces loading of the https: version always.



回答2:

The above answer incomplete. You have to do one more thing.

Step 1: Adding HTTPS

Do what the other answer told you to do, change the mixpanel code, change http://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js to https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js

Step 2: Modifying content security in your manifest.json

Update the content_security_policy property in your manifest.json: { ..., "content_security_policy": "script-src 'self' https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js; object-src 'self'", ... }

This relaxes the default content security policy.

Step 3 [optional]: Adding Google Analytics

If you also want Google Analytics as well, you can add it like this: { ..., "content_security_policy": "script-src 'self' https://ssl.google-analytics.com https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js; object-src 'self'", ... }

I learned how to do this from Google's own tutorial on how to add Google Analytics.



回答3:

You could use this script to load mixpanel from custom url.

<script>
  window.MIXPANEL_CUSTOM_LIB_URL = 'lib/mixpanel/mixpanel.js';
</script>