The proposal would be to add the CSP header, "X-Content-Security-Policy:" with a policy-uri pointing to a static file (which can be cached by the user agent).
Because the specification says the UA must compute the intersection for multiple CSP headers, if a system administrator imposes a more restrictive policy (e.g., via Apache's "append header" directive), it doesn't matter if this feature is enabled by default or not -- a supporting UA will use the more restrictive policy.
This is a wontfix. The base restrictions are:
Maybe we can re-consider, maybe there would be a technical solution to have Piwik run in this CSP scenario?
@mattab It would be nice if Piwik included CSP in the admin backend for increased security (e.g prevent plugins from executing JS or loading resources from suspicious sources). CSP headers are only sent for documents, not for other page resources, so this won't interfere with calls to the tracking JS at all.
A brief overview on CSP can be found at http://content-security-policy.com
To be clear, this issue is also about not using
eval in piwik.js since #5960 was closed as a duplicate of this
@tsteur Having CSP in our LTS would really help especially some security strict Enterprise environment. Could you please do assessment what it would take not to use
eval - is it possible, while still bundling the JSON encoder?
we can replace it with JSON 3 https://bestiejs.github.io/json3/
I think there's only one other eval in
Legacy piwik.js compatibility ftw and this one we can replace probably without much work.
Update: in #8896 we removed all uses of
eval the piwik.js, by replacing JSON2 with JSON3. Latest piwik.js without eval is here: https://github.com/piwik/piwik/blob/master/js/piwik.js
We are one step closer to CSP support! :+1:
What is our next step for fully supporting CSP?
I'm not sure which directives to set for CSP. @robocoder mentioned no inline scripts see https://github.com/piwik/piwik/issues/1542#issuecomment-48299980 This can be done but need to document how to do it in FAQ.
Which directives should one set to test it properly?
Keep in mind, that IE 10-11 uses "X-Content-Security-Policy" and Safari < 7 uses "X-Webkit-CSP" in case you want to support those as well.
You should consider default-src, script-src, style-src, frame-ancestors; frame-src. See http://www.w3.org/TR/CSP/
Also a good idea would be to add 'upgrade-insecure-requests' for HTTPS environments, see: http://www.w3.org/TR/upgrade-insecure-requests/ and enable Strict-Transport-Security
To check if everything is working correctly, you can use 'report-uri', to log CSP violations (a good service is https://report-uri.io for setting this up).
Current browser support: http://caniuse.com/#feat=contentsecuritypolicy,contentsecuritypolicy2
Tested and worked for me. Took me a while to figure out why it didn't work in the beginning until I noticed I was using the
X-Content-Security-Policy which doesn't work under Chrome but
Content-Security-Policy did. As you mentioned the other one works with IE.
Used this in
# Loading piwik.js from different domain (apache.piwik) Header set Content-Security-Policy "default-src 'self'; script-src 'self' http://apache.piwik; style-src 'self'; frame-ancestors 'self'; frame-src 'self';" # Loading piwik.js from same domain as Piwik Header set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; frame-ancestors 'self'; frame-src 'self';"
piwik.js the file was refused to load but with new one worked and I could create a Tracker instance via
Piwik.getTracker(...). Inline script did not work, got
Refused to execute inline script because it violates the following Content Security Policy directive as expected.
@tsteur If you use default-src, you don't need to specify the other *-src if they all use the same value.
CSP might have an impact on 3rd party plug-ins, as they may include files from a CDN or other external resources. So this change should be documented clearly.
I only tested for
piwik.js so far. Piwik itself uses lots of inline-script and I think Angular requires
eval to work etc. We should definitely mention that when a website uses other 3rd party plugins or a CDN they might have to whitelist further domains etc.
FAQ could be something like this:
Yes, Piwik can be used with CSP. However, you cannot use the standard tracking code generated by the Tracking Code Generator in the Piwik UI as it is not allowed to use inline scripts when having CSP enabled. CSP is a security concept to prevent cross-site scripting (XSS) attacks as well as related attacks.
Instead make sure to put the tracking code into files like this:
<script src="http://example.com/piwik/piwik.js" async defer> <script src="http://example.com/tracking.js">
piwik.js should be loaded from your Piwik server and
tracking.js should contain the actual tracking calls like this:
var idSite = 1; var piwikTrackingApiUrl = 'http://example.com/piwik/piwik.php'; var _paq = _paq || ; _paq.push(['setTrackerUrl', piwikTrackingApiUrl]); _paq.push(['setSiteId', idSite]); _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']);
Make sure to specify the correct
idSite if needed and to replace the Piwik Tracking API URL. You can build this URL by appending
/piwik.php to your Piwik domain.
If you load
piwik.js from a different domain make sure to allow the Piwik domain like this:
An example response header looks like this:
Header set Content-Security-Policy "default-src 'self'; script-src 'self' http://example.com; style-src 'self'; frame-ancestors 'self'; frame-src 'self';"
If CSP should work in all browsers you might have to add further headers. At the time of writing this article you might as well need to set
X-WebKit-CSP for Safari and
X-Content-Security-Policy for Internet Explorer support. Read more about Content Secrutiy Policy.
This issue has been closed but AFAICT the Matomo admin still doesn't have a CSP.
It is a good practice to return a
Content-Security-Policy header as it prevents different types of XSS attacks.
I know Matomo still uses inline scripts but we can allow them in the CSP and IMHO having a loose CSP is better than no CSP at all.
Here is what we used on our server:
Content-Security-Policy: default-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:
Here is what it means:
It's also a good idea to define the following headers:
X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block X-Frame-Options: DENY
Please never use CSP with unsafe-inline or unsafe-eval, it de facto eliminates XSS protection. Instead, generate
sha265- hashes to explicitly whitelist inline code snippets (see: https://content-security-policy.com/#source_list):
$nonce = uniqid(); header("Content-Security-Policy: … script-src 'nonce-" . $nonce . "'"); // … echo '<script nonce="' . $nonce . '">alert("hello world")</script>'