Script injection considerations when building a Matomo integration

Hi all,

Apologies in advance for the long post.

We are considering to build a Matomo integration for our CMS.

For simplicity, let me explain this with an analogy: We are a SaaS somewhat similar to wordpress.com (the SaaS, not the self-hosted!). Our customers have an account, enter content in our CMS which gets then published to something such was bob.ourawesomecms.com.

The system is designed to be simple and we want to prevent any form of script injection by our publishers. One reason: Readers/commenters of the blog can have an account with us as well, and it is in our interest to protect their personal data and identity (e.g. by not exposing this in the full extent to the publisher).

To integate a Matomo tracking, we are planning to add a configuration to our CMS which allows Bob to input the following two settings:

  1. matomo_url (either pointing to https://bob.matomo.cloud or https://matomo.bobsmatomoinstance.com)
  2. site_id (not relevant in the following)

Based on this information we build the appropriate tracking JS and inject it into the pages shown on Bob’s site. Very simplified like so:

<script src="${matomo_url}/matomo.js" async defer></script>
// Matomo initialization here

So far so good.

The issue, about which I am concerned, arises, if Bob decides to misuse the Matomo integration for not doing Matomo tracking at all, but injecting his own evil script:

  1. Put a fake matomo.js on https://this-is-not-a-matomo-instance.com/matomo.js
  2. The script would e.g. record user activity such as entering username and password of the commenters (who should stay anonymous to Bob) and submit this back to https://this-is-not-a-matomo-instance.com

In other words: We cannot really ensure that the matomo_url is a real Matomo instance or something just pretending to be a Matomo. Any attempts on our end to ensure that matomo_url is an actual Matomo instance (by calling an API endpoint, etc.) can obviously easily circumvented (or later be switched).

The only mitigation which I see: Just do not load matomo.js from any user-supplied source, but instead serve it from our own trusted source. However, the FAQ advise against this:

  • Local copy of piwik.js outdated Some users make a local copy of piwik.js on a different server than their Matomo installation. This is not officially supported and causes issues when the piwik.js bundled with Matomo is updated and not compatible with the previous version (for example, this is the case in Matomo 0.5.5). Please check that your Matomo JS tracking code is exactly the one given in the Matomo admin screen.
  • So, is this still a no-no? (considering the text speaks of v0.5.5 from long ago)
  • Is it doable if we ensure that the matching version (v2, v3, or v4) of the JS is used? E.g. by adding a version toggle to the configuration?
  • Or is v4 of the script even backwards-compatible to older Matomo versions?

Or are there any other recommended approaches to this?

Many thanks for your attention!

1 Like

Hi,

If you don’t want users to execute any JS (which is understandable in your context), then I don’t think there is any way you can securely allow them to load a javascript file from their origin.

Therefore you probably have to go with providing the matomo.js.
While the basic Tracking API didn’t change in a very long time meaning the latest matomo.js is backwards compatibility with quite old servers (except of course for features that did change since (like page load performance). But assuming your users are on one of the latest Matomo versions, that should never really become an issue.

The bigger issue (and why hardcoding matomo.js isn’t recommended in general) is that Matomo users can install plugins on their servers that modify the matomo.js (e.g. premium plugins like form or media analytics).
But if you make it clear to your users that that won’t work, then you should probably be fine with serving one matomo.js (the one of the latest matomo.js or alternatively a few of them at the choice of the user) and allowing users to only select the Matomo URL where the data is sent to.

But even then you have to be a bit careful so you don’t accidentally send personal data from your visitors to other peoples Matomo servers. Of course features like custom dimension, custom events or User ID should not be used, but that already belongs in the category of not allowing users to add arbitrary JS.

But of course if the URL or the Title of a page might contain personal information, then this is tracked by Matomo. And also I can’t say how much you can more the question of consent, etc. to your users (as they might not have set their Matomo to e.g. anonymize IPs, etc.).

1 Like

Thank you Lukas, that’s definitely very valuable information!

– Philipp