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

CSP unsafe-inline #11720

Open
lchandelier opened this issue May 19, 2017 · 26 comments
Open

CSP unsafe-inline #11720

lchandelier opened this issue May 19, 2017 · 26 comments
Labels
Bug For errors / faults / flaws / inconsistencies etc. c: Security For issues that make Matomo more secure. Please report issues through HackerOne and not in Github.

Comments

@lchandelier
Copy link

Hi,
I've setted up Piwik like you suggest in you FAQ. However, to be able to use it, I have to allow script-src 'unsafe-inline', which I don't want.

Will you make an enhancement to avoid this?

@godofdream
Copy link

you could use 'nonce-myrandomstring' or move the snippet into an external js file

@lchandelier
Copy link
Author

My piwik.js file is on my server and the snippet is already in an external file. I've tried to add the nonce on it but I still have the issue.

@mattab
Copy link
Member

mattab commented Jun 21, 2017

Hi @mchandelier do you confirm that our instructions at https://piwik.org/faq/general/faq_20904/ are outdated and that it doesn't just work?

@lchandelier
Copy link
Author

Hi @mattab,
It doesn't work for me. The only exception I have from the FAQ is that piwik.js is loaded from the same domain. I may do something wrong but I really don't see what.

@mattab
Copy link
Member

mattab commented Jun 22, 2017

Ok we will need to investigate.

If anyone knows about CSP feel free to take a look (Pull request welcome!).

@mbarbey
Copy link

mbarbey commented Aug 15, 2017

Hi @mattab,
Did you have some news for this problem ?

I am using the piwik script in an external file too to prevent having any inline js code in my pages, and I am encountering the same problem as @mchandelier.

Do you have an idea why the piwik script, which is embedded in an external script, require using script-src 'unsafe-inline' ?

@mattab mattab added the Bug For errors / faults / flaws / inconsistencies etc. label Feb 27, 2019
@mattab
Copy link
Member

mattab commented Jun 28, 2019

We also got another feedback today on the CSP FAQ:

Here was the feedback:

I do not understand this guide. Based on this guide I cannot make Matomo CSP-compatible.
Where should I place this script tags? Head or body? Footer?
Why do I need two files? Why can't I just have tracking.js and paste there the normal tracking code?

@frjo
Copy link

frjo commented Jan 16, 2020

I followed the instructions in https://matomo.org/faq/general/faq_20904/ and it seems to be working. I use this policy on my server.

Header set Content-Security-Policy "default-src 'self'; \
  object-src 'none'; \
  script-src 'self' https://matomo.example.org"

See for example this site: https://xdeb.org/.

I have implemented this in my Hugo theme frjo/hugo-theme-zen.

@daniol
Copy link

daniol commented Jun 21, 2020

It would be better to supply the sideID and other parameters via URL parameters to the tracking script. This way would be 100% CSP-compliant without the need of using a second JS file.

The matomo script would read this attributes from document.currentScript and build the _paq object.

<script src="https://example.com/matomo.js?setSiteId=1&trackPageView&enableLinkTracking"></script>

document.currentScript.src -> outputs https://example.com/matomo.js?setSiteId=1&trackPageView&enableLinkTracking

The parameters can be parsed via URLSearchParams an transformed to _paq within 5 lines of code.

const urlParams = new URLSearchParams(document.currentScript.src.substr(document.currentScript.src.indexOf('?')));
for(const entry of urlParams.entries()) {
	if(entry[1] !== undefined) _paq.push([entry[0], entry[1]]);
	else _paq.push([entry[0]]);
}

Here for an IE polyfill: https://github.com/amiller-gh/currentScript-polyfill

@ixbarbarbar
Copy link

ixbarbarbar commented Aug 15, 2020

Hi all,
I see many tickets on the CSP and apparently only this one is always opened.

On the admin interface, there are many usage of the inline script and a usage also of eval (I see another ticket for the eval but apparently it was close with the correction).

The more easy patch is to use nonce base64 encode for each line where JS inline called (also for css).
I see that already a module to generate a nonce but not for the same function.

Example of code can be added on the core\Twig.php (maybe another place is better...)

class PiwikTwigNonceJs extends \Twig_Extension {
    private $nonce;

    /**
     * Generates a random nonce value in base64.
     * @return string
     */
    public function getNonce() : String
    {
        // Only is nonce is null
        if (!$this->nonce) {
            $this->nonce = base64_encode(random_bytes(20));
        }

        return $this->nonce;
    }

    /**
     * @return array
     */
    public function getFunctions()
    {
        return [
            new Twig_SimpleFunction('csp_nonce', [$this, 'getNonce']),
        ];  
    }   
}

// @ the end of the Twig class
$this->twig->addExtension(new PiwikTwigNonceJs());

Modify the template file to add the meta at the begin of the (example on plugins/Morpheus/templates/layout.twig)

<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'nonce-{{ csp_nonce() }}';">

And each template contains the script inline like plugins/Morpheus/templates/_jsGlobalVariables.twig

<script type="text/javascript" nonce="{{ csp_nonce() }}">

@perdittmann
Copy link

perdittmann commented Feb 11, 2021

Hello everyone,
I am still struggling to get my Matomo installation (on a shared hosting server) working with a CSP in place that does not include script-src 'unsafe-inline' and 'unsafe-eval' (which to my understanding would make the whole CSP rather pointless).

ixbarbarbar's solution gave me this:

The following error just broke Matomo (v4.1.1):

Class 'Twig_Extension' not found
in /var/www/example.com/matomo/core/Twig.php line 626

I changed
/core/Twig.php
/plugins/Morpheus/templates/layout.twig
/plugins/Morpheus/templates/_jsGlobalVariables.twig
/plugins/Morpheus/templates/_sparklineFooter.twig
/plugins/Morpheus/templates/javascriptCode.twig

Is there something I missed?
Many thanks in advance for your help!

@diosmosis
Copy link
Member

Hi @perdittmann, that code is using an old version of twig that matomo doesn't use anymore. Instead of the /core/Twig.php changes you made, these changes should work:

https://github.com/matomo-org/matomo/compare/csp-nonce?expand=1

can you try them out?

@perdittmann
Copy link

Hi @diosmosis, thank you for your help!
I managed to isert the code into the two files you mentioned, and didn't produce a critical error this time. :-)

I updated every instance of <script> tags with the nonce-Code (throughout the plugins folder, about 45). I suppose I will have to do that again with every Matomo update?

Alas, the admin panel is still blank below the blue header.
I found one script still without the nonce:

    <script type="text/javascript">
    var translations = {"CorePluginsAdmin_NoZipFileSelected": …

(close to the end of the < head >).
I think it is called by {{ includeAssets({"type":"js"}) }} – but so far, I have been able to figure out where the corresponding getJsInclusionDirective is defined.

Am I in luck and you could point me in the right direction again?
Thanks a lot!

@perdittmann
Copy link

If there only was a way to search the entire source code … 🤦
I got where I needed to be, but I am out of my depth again.

getJsInclusionDirective() is defined in core/AssetManager.php.
Since it is a PHP file, the twig syntax to add the nonce does not work, and I couldn't figure out how to get to the nonce in PHP.
Do you maybe have an idea? Thanks!

@diosmosis
Copy link
Member

hi @perdittmann, you can use grep or a similar tool to find <script elements in the code. I'm also going to ask that you ask future questions about the code base on the forums: https://forum.matomo.org/ as you may not get a response here

@perdittmann
Copy link

(I had just realized I can search the source code right here, that was me being self-deprecating. 😄)
Thanks for the link and for your help. I will try my luck there!

@Ryonez
Copy link

Ryonez commented Nov 30, 2021

Do we have a CSP compliant solution yet?

@justinvelluppillai justinvelluppillai added the c: Security For issues that make Matomo more secure. Please report issues through HackerOne and not in Github. label Oct 27, 2022
@justinvelluppillai justinvelluppillai added this to the For Prioritization milestone Oct 27, 2022
@justinvelluppillai
Copy link
Contributor

@mattab I have just added this issue for prioritisation - it would be a good security improvement to either update the docs to provide guidance on this or suggest solutions.

@Benjamin-K
Copy link

This issue came up in a Pentest we had for one of our customers. The CSP can be setup in a good way in the frontend (either using a separate file or by using a nonce). But the Matomo backend currently can not be used without unsafe-inline and unsafe-eval. I think, many of these issues can be fixed by simply using a nonce (can be the same for all inline scripts / styles). This at least fixes unsafe-inline. For the unsafe-eval part: I don't know, why this is really needed. Can anybody explain this here? I do not want any evil browser extension to be able to run code in "my" Matomo instances for example.

@sgiehl
Copy link
Member

sgiehl commented Nov 16, 2023

without unsafe-eval methods like eval or Function would be disabled in javascript. Those methods are used not only in the javascript tracker, but may also be used within the javascript code. So removing it would most likely break Matomo.

@Benjamin-K
Copy link

The tracker itself (matomo.js) does not use any unsafe-eval methods – we do not allow unsafe-eval in our sites CSP and Matomo still works. Those functions are only used in the backend.

I know that this is not a task that would be solved in a few hours. But for Matomo this would make a big difference when it should be used by big companies or public authorities as they might complain about the weak CSP header in the backend.

@sgiehl
Copy link
Member

sgiehl commented Nov 16, 2023

You're right. piwik.js only uses that in a part that is used for tests only, so that won't occur when tracking.
I only did a quick search through the code base and some parts are using those methods, and replacing that might not be too trivial, as some parts a provided by third party libs, so we would need to search for replacements.

@Benjamin-K
Copy link

With third party libs you mean plugins? If that's the case, we could try to make the Matomo core work with CSP and only remove the unsafe-eval and unsafe-inline if some config is set to true (like force_ssl does). Then we can document that somewhere so people can decide on their own on setting a stronger CSP header and therefore are maybe unable to use some plugins or leave the config as is.

@totola-clx
Copy link

Hi,
I also have the same problem described by @Benjamin-K , third party PenTests have repeatedly mentioned this problem on our Matomo installations.
The problem reported is not on the tracked application, but on Matomo Web UI, in particular on the login page, since the VAPT is executed in "black-box" mode.

I was wondering:

  • Does the login page make use of plugins and/or of the above mentioned Javascript libraries?
  • Would it be possible to add the CSP strict policy to the login page only?

Cristian

@Benjamin-K
Copy link

Hi @totola-clx,
thanks for giving further feedback. I think adding a CSP strict policy to the login page only would only be a "Quick win". To make Matomo more secure, the CSP should really be more strict in the backend in total.

Besides that: The login page at least uses some JS. I don't know whether some of that JS is required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For errors / faults / flaws / inconsistencies etc. c: Security For issues that make Matomo more secure. Please report issues through HackerOne and not in Github.
Projects
None yet
Development

No branches or pull requests