2

How can we remove this script injector system and clear functions from memory?

Briefing) Recently the malfeasants at Bigcommerce created an analytics injector (JS) under guise of "monitoring" that is locked in a global variable. They have pushed it to all their 50,000 front facing stores without consent from any OP's. This puts in 2 JS libraries and sets up (plain code) triggers for them to track customer, behavior, and store plans throwing data to their shared 3rd party analytics bay. The issue is that although they run the code, they do not own rights to put in 3rd party libraries like this across thousands of domains out of their realm. Does anyone have ideas on how we can kill this + remove from memory? Is this even legal for them to do?

1) The injector is found in the shared global %%GLOBAL_AdditionalScriptTags%% in the HTMLhead.html panel, which means it non-accessible. The AdditionalScriptTags is also dynamic, meaning it loads different JS helpers based on what page is being requested. Removing the variable is a no-go for that reason.

2) The injector uses various DSL variables PHP side to build out its settings. Here is what it looks like in <head> as I browse logged into our store as a customer. This is putting 2 lines for 2 separate libraries which I will define below (note certain tokens hidden as 1234)

(function(){
    window.analytics||(window.analytics=[]),window.analytics.methods=["debug","identify","track","trackLink","trackForm","trackClick","trackSubmit","page","pageview","ab","alias","ready","group","on","once","off","initialize"],window.analytics.factory=function(a){return function(){var b=Array.prototype.slice.call(arguments);return b.unshift(a),window.analytics.push(b),window.analytics}};for(var i=0;i<window.analytics.methods.length;i++){var method=window.analytics.methods[i];window.analytics[method]=window.analytics.factory(method)}window.analytics.load=function(){var a=document.createElement("script");a.type="text/javascript",a.async=!0,a.src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js";var b=document.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)},window.analytics.SNIPPET_VERSION="2.0.8",window.analytics.load();

    // uncomment the following line to turn analytics.js debugging on
    // shows verbose events and other useful information
    // analytics.debug();

    var storeId = '123456',
        userId = '921';

    // initialize with Fornax and Segment.io
    var providers = {
        Fornax: {
            host: 'https://analytics.bigcommerce.com',
            cdn: 'http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js',
            defaultEventProperties: {
                storeId: storeId
            }
        },
        'Segment.io': {
            apiKey: '1sbkkbifdq'
        }
    };

    var fornaxEnabled = false;
    var segmentIOEnabled = false;
    var isStorefront = true;

    if (!fornaxEnabled) {
        delete providers.Fornax;
    }

    if (!segmentIOEnabled || isStorefront) {
        delete providers['Segment.io'];
    }

    analytics.initialize(providers);


    // identify this user
    analytics.identify(
        userId || null,
        {"name":"Test Dude","email":"test@test.com","storeHash":"123456","storeId":123456,"namespace":"bc.customers","storeCountry":"United States","experiments":{"shopping.checkout.cart_to_paid":"legacy_ui","search.storefront.backend":"mysql"},"storefront_session_id":"6b546880d5c34eec4194b5825145ad60d312bdfe"}
    );
})();

3) The output libraries are found as 2 references in the <head> and as you see if you own/demo a BC store, are rather un-touchable:

<script type="text/javascript" async="" src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js"></script>
<script type="text/javascript" async="" src="http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js"></script>

How can we break the injector and these trackers and prevent them from loading? Is there a way to remove their functions from memory? Speaking on behalf of many thousands of OP's and segment.io here, we are all at our wits end with this.

dhaupin
  • 1,613
  • 2
  • 21
  • 24
  • Have you tried contacting Bigcommerce and asking for the removal of this? – Adjit Apr 24 '14 at 13:46
  • @Adjit Yes we tried multiple times to get it removed under ticket #00202626. They did remove the Fornax part since it was hanging our store, as well as exposed plain code store plan, but other than that they simply ignore the request OR make it seem like we are complaining about a pagespeed issue. Segment.io has been in contact with their CTO about it for the last few days, but have seen no results yet. – dhaupin Apr 24 '14 at 15:35
  • do you have access to these scripts or source files? Can you edit the layout of your pages from your webserver? – Adjit Apr 24 '14 at 15:38
  • Yes we have access to basic templating and whatnot, however the issue is that step 2) injector is locked inside a variable which we can not edit. If we remove the variable it breaks dynamic script inclusions (such as cart, modals, etc). We cant guess the scripts since they change across page styles, and since this would hinder any future updates they do. So, in templating side/editor we see just an object called %%GLOBAL_AdditionalScriptTags%%. When BC parses, it dumps in that injector via that object, which dumps in those calls in step 3) via secondary async. Seems strange to me. – dhaupin Apr 24 '14 at 15:51
  • I would take a look at this post regardless : http://stackoverflow.com/questions/10412651/how-can-i-remove-script-elements-before-they-are-being-executed it shows you how to remove a script before it is executed, thus it breaks the connection with Bigcommerce. Although it will be tough for you to confirm this as you do not see their analytics. I know this method should work to at least remove the scripts in step 3, but not sure exactly what step 2 looks like in your `` – Adjit Apr 24 '14 at 15:53
  • Thank you Adjit for that link, the concept seems to work in consoles and things. We will begin testing this method right away in BC, modify a solution above, and vote up your answer if successful. Appreciate your time with this! – dhaupin Apr 24 '14 at 18:25
  • Not a problem! My company uses Google Analytics, but that is strictly internal. I am also unfortunately unsure of whether or not the injector will be affected. If like you said the output libraries are in those script tags, if those are the libraries in which the analytics are output to then I would assume the injector will have nowhere to output the information to. – Adjit Apr 24 '14 at 20:02
  • Hi dhaupin, have you test Adjit's method to remove fornax.min.js and analytics.min.js. I tried by inserting Adjit's code into HTMLHead.html before any other js, but I got one blank homepage. If you fixed this issue, can u please share it to us with my thx. – John Yin Jul 10 '14 at 07:03
  • Hi guys, yes that is correct - white page by default. We were able to create the script destroyer but were unable to get it working properly before we moved carts. It would act like "all or nothing" and destroy too much. The theory that Adjit posted is very close, however it was just too hardcore to gracefully work with BC methods. I hate to leave this question open, but we are now using OpenCart for all stores and will no longer be dealing with Bigcommerce and its ways :) – dhaupin Jul 10 '14 at 15:09

2 Answers2

2

Per the question I linked, for you case to at least remove the scripts from Step 3 this is what you should do :

var xhr = new XMLHttpRequest,
    content,
    doc,
    scripts;

xhr.open( "GET", document.URL, false );
xhr.send(null);
content = xhr.responseText;

doc = document.implementation.createHTMLDocument(""+(document.title || ""));

doc.open();
doc.write(content);
doc.close();


scripts = doc.getElementsByTagName("script");
//Modify scripts as you please
[].forEach.call( scripts, function( script ) {
    if(script.getAttribute("src") == "http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/fornax.min.js"
       || script.getAttribute("src") == "http://cdn2.bigcommerce.com/r6cb05f0157ab6c6a38c325c12cfb4eb064cc3d6f/app/assets/js/analytics.min.js") {

        script.removeAttribute("src");
    }
});

//Doing this will activate all the modified scripts and the "old page" will be gone as the document is replaced
document.replaceChild( document.importNode(doc.documentElement, true), document.documentElement);

You must make sure that this is the first thing to run, otherwise the other scripts can and will be executed.

Adjit
  • 10,134
  • 12
  • 53
  • 98
  • HI Adjit, i tried, but it looks like the home page to be blank page – John Yin Jul 10 '14 at 06:10
  • I am going to vote this up for theory - although the script itself is not a fit for BC, the theory is correct for destroy and regen. – dhaupin Jul 10 '14 at 15:12
  • hi dhaupin, i tried this JS, it's not working. If you can find the right JS, it would be great definitely. While I am afraid, maybe we can't, for that's not BC like and they must have some way to hide us to do this – John Yin Jul 11 '14 at 06:33
  • @JohnYin you must make sure that it is running before your analytics library. Because really, the only way to remove it is using some sort of pre-script before the page is loaded. – Adjit Jul 11 '14 at 13:13
2

I've been hacking away at this too and I found something that works well to disable most/all of it.

Before this line:

%%GLOBAL_AdditionalScriptTags%%

Use this code:

<script type="text/javascript">
        window.bcanalytics = function () {};
</script>

So you will end up with something like this:

%%GLOBAL_AdditionalScriptTags%%
<script type="text/javascript">
        window.bcanalytics = function () {};
</script>

The <script> tags from part 3 of your question will still load as those are always PREpended before the first non-commented out <script> tag, but most, if not all, the analytics functionality will break, including external calls, and even fornax.js won't load. Hope this helps.

Andre Bulatov
  • 1,090
  • 3
  • 16
  • 47
  • Nice idea! Unfortunately they kicked us out of their platform because of this. Apparently removing a scumbag analytics lib is "against their terms" since it's not available in a schema which clients can edit. – dhaupin Jul 16 '15 at 15:09
  • Oh wow, just like that? No warnings or anything? And so you ended up succeeding in doing this -- if so, please share how? – Andre Bulatov Jul 17 '15 at 01:28