diff options
author | Peter Zhang <peter@innocraft.com> | 2022-05-18 01:12:21 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-18 01:12:21 +0300 |
commit | 35957fc5aeecf9f6f795e4e8e005f9d37fab7a2d (patch) | |
tree | ea88e41c8643d469bdb0352e492d401ae5bdc09a | |
parent | 3860159eaa190561896dcade11268193b4b4630b (diff) |
[security] Force matomo.org related requests to use ssl as default (#19098)
* Update dataTable.js
update database table
* Update dataTable.js
update table bug
* Update dataTable.js
shorter the query
* update screenshot
update screenshot
* Update dataTable.js
make table size stable
* Revert "Update dataTable.js"
This reverts commit 1a72e1d9580172414fb147cda9e66f4927f4b2ae.
* Update dataTable.js
update columns
* Revert "update screenshot"
This reverts commit c11aec88af44668171d2ee14e7a502b5fb04126f.
* force ssl to api and plug
force ssl to api and plug
* force request to ssl
force request to ssl
* Update Http.php
update tests
* update tests
update condition only on matomo.org
* update checks
update checks
* update default to https
update default to https
* update phpcs check
update phpcs check
* Update plugins/Marketplace/config/config.php
* add config force ssl on market place
add config force ssl on market place
* Update plugins/Marketplace/config/config.php
Co-authored-by: Justin Velluppillai <justin@innocraft.com>
* update config
update config
* update config
update config
* built vue files
* remove double diagnostic
remove double diagnostic
* force api using https
force api using https
* update tests
update tests
* update feed back
update feed back
* Remove unused use
* update failed display message
update failed display message
* Update plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php
Co-authored-by: Justin Velluppillai <justin@innocraft.com>
* Minor text tweak
* update hardcode to translation
update hardcode to translation
* update translation
update translation
* update language and some logic
update language and some logic
* run test
run test
* trigger test
trigger test
* update screenshot
update screenshot
Co-authored-by: sgiehl <stefan@matomo.org>
Co-authored-by: Justin Velluppillai <justin@innocraft.com>
Co-authored-by: peterhashair <peterhashair@users.noreply.github.com>
Co-authored-by: Ben Burgess <88810029+bx80@users.noreply.github.com>
-rw-r--r-- | config/global.ini.php | 6 | ||||
-rw-r--r-- | core/Http.php | 13 | ||||
-rw-r--r-- | plugins/CoreUpdater/Controller.php | 14 | ||||
-rw-r--r-- | plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php | 17 | ||||
-rw-r--r-- | plugins/CoreUpdater/ReleaseChannel.php | 6 | ||||
-rw-r--r-- | plugins/CoreUpdater/Updater.php | 13 | ||||
-rw-r--r-- | plugins/CoreUpdater/tests/Integration/ReleaseChannelTest.php | 2 | ||||
-rw-r--r-- | plugins/Installation/lang/en.json | 5 | ||||
-rw-r--r-- | plugins/Marketplace/Api/Client.php | 17 | ||||
-rw-r--r-- | plugins/Marketplace/Controller.php | 3 | ||||
-rw-r--r-- | plugins/Marketplace/config/config.php | 12 | ||||
-rw-r--r-- | plugins/Marketplace/config/test.php | 9 | ||||
-rw-r--r-- | plugins/UsersManager/NewsletterSignup.php | 4 | ||||
-rw-r--r-- | tests/UI/expected-screenshots/UIIntegrationTest_admin_diagnostics_configfile.png | 4 |
14 files changed, 73 insertions, 52 deletions
diff --git a/config/global.ini.php b/config/global.ini.php index 14276efcd7..ffe327416e 100644 --- a/config/global.ini.php +++ b/config/global.ini.php @@ -706,7 +706,7 @@ enable_trusted_host_check = 1 ; The API server is an essential part of the Matomo infrastructure/ecosystem to ; provide services to Matomo installations, e.g., getLatestVersion and ; subscribeNewsletter. -api_service_url = http://api.matomo.org +api_service_url = https://api.matomo.org ; When the ImageGraph plugin is activated, report metadata have an additional entry : 'imageGraphUrl'. ; This entry can be used to request a static graph for the requested report. @@ -800,6 +800,10 @@ enable_update_communication = 1 ; If you may need to download GeoIP updates or other stuff using other protocols like ftp you may need to extend this list. allowed_outgoing_protocols = 'http,https' +; This option forces matomo marketplace and matomo api requests to use Https for improved security +; If you have a problem loading the marketplace, please disable this config option +force_matomo_ssl_request = 1 + ; Comma separated list of plugin names for which console commands should be loaded (applies when Matomo is not installed yet) always_load_commands_from_plugin= diff --git a/core/Http.php b/core/Http.php index d944f5fb25..6d0117a935 100644 --- a/core/Http.php +++ b/core/Http.php @@ -195,6 +195,7 @@ class Http throw new Exception('Too many redirects (' . $followDepth . ')'); } + $aUrl = preg_replace('/[\x00-\x1F\x7F]/', '', trim($aUrl)); $parsedUrl = @parse_url($aUrl); @@ -1109,4 +1110,16 @@ class Http return array($proxyHost, $proxyPort, $proxyUser, $proxyPassword); } + + /** + * Checks the request is over SSL + * @return bool + */ + public static function isUpdatingOverHttps() + { + $openSslEnabled = extension_loaded('openssl'); + $usingMethodSupportingHttps = (Http::getTransportMethod() !== 'socket'); + + return $openSslEnabled && $usingMethodSupportingHttps; + } } diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php index 16a2529dfa..54ab1e9131 100644 --- a/plugins/CoreUpdater/Controller.php +++ b/plugins/CoreUpdater/Controller.php @@ -18,7 +18,6 @@ use Piwik\Development; use Piwik\Filechecks; use Piwik\FileIntegrity; use Piwik\Filesystem; -use Piwik\Http; use Piwik\Nonce; use Piwik\Option; use Piwik\Piwik; @@ -28,10 +27,10 @@ use Piwik\Plugins\Marketplace\Plugins; use Piwik\SettingsPiwik; use Piwik\SettingsServer; use Piwik\Updater as DbUpdater; +use Piwik\Updater\Migration\Db as DbMigration; use Piwik\Version; use Piwik\View; use Piwik\View\OneClickDone; -use Piwik\Updater\Migration\Db as DbMigration; class Controller extends \Piwik\Plugin\Controller { @@ -92,7 +91,7 @@ class Controller extends \Piwik\Plugin\Controller { Common::sendHeader('Content-Type: application/javascript; charset=UTF-8'); Common::sendHeader('Cache-Control: max-age=' . (60 * 60)); - + $files = array( "node_modules/jquery/dist/jquery.min.js", "node_modules/jquery-ui-dist/jquery-ui.min.js", @@ -126,7 +125,7 @@ class Controller extends \Piwik\Plugin\Controller public function newVersionAvailable() { Piwik::checkUserHasSuperUserAccess(); - + if (!SettingsPiwik::isAutoUpdateEnabled()) { throw new Exception('Auto updater is disabled'); } @@ -452,11 +451,4 @@ class Controller extends \Piwik\Plugin\Controller return PluginManager::getInstance()->getIncompatiblePlugins($piwikVersion); } - public static function isUpdatingOverHttps() - { - $openSslEnabled = extension_loaded('openssl'); - $usingMethodSupportingHttps = (Http::getTransportMethod() !== 'socket'); - - return $openSslEnabled && $usingMethodSupportingHttps; - } } diff --git a/plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php b/plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php index dd571b8c15..b90f9115c7 100644 --- a/plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php +++ b/plugins/CoreUpdater/Diagnostic/HttpsUpdateCheck.php @@ -7,7 +7,8 @@ */ namespace Piwik\Plugins\CoreUpdater\Diagnostic; -use Piwik\Plugins\CoreUpdater; +use Piwik\Config\GeneralConfig; +use Piwik\Http; use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult; use Piwik\Translation\Translator; @@ -31,12 +32,18 @@ class HttpsUpdateCheck implements Diagnostic { $label = $this->translator->translate('Installation_SystemCheckUpdateHttps'); - if (CoreUpdater\Controller::isUpdatingOverHttps()) { + if (GeneralConfig::getConfigValue('force_matomo_ssl_request') === 0) { + //if config is off, show info + $comment = $this->translator->translate('Installation_MatomoSslRequestConfigInfo');; + return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_INFORMATIONAL, $comment)); + } elseif (Http::isUpdatingOverHttps()) { + // successful using https return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK)); + } else { + // failed to request over https + $comment = $this->translator->translate('Installation_SystemCheckUpdateHttpsNotSupported'); + return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)); } - $comment = $this->translator->translate('Installation_SystemCheckUpdateHttpsNotSupported'); - - return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)); } } diff --git a/plugins/CoreUpdater/ReleaseChannel.php b/plugins/CoreUpdater/ReleaseChannel.php index 5e5f35a511..50d17251bf 100644 --- a/plugins/CoreUpdater/ReleaseChannel.php +++ b/plugins/CoreUpdater/ReleaseChannel.php @@ -9,13 +9,13 @@ namespace Piwik\Plugins\CoreUpdater; use Piwik\Common; -use Piwik\Config; use Piwik\Db; use Piwik\Http; +use Piwik\Plugins\Marketplace\Api\Client; use Piwik\Plugins\SitesManager\API; +use Piwik\UpdateCheck\ReleaseChannel as BaseReleaseChannel; use Piwik\Url; use Piwik\Version; -use Piwik\UpdateCheck\ReleaseChannel as BaseReleaseChannel; abstract class ReleaseChannel extends BaseReleaseChannel { @@ -31,7 +31,7 @@ abstract class ReleaseChannel extends BaseReleaseChannel 'timezone' => API::getInstance()->getDefaultTimezone(), ); - $url = Config::getInstance()->General['api_service_url'] + $url = Client::getApiServiceUrl() . '/1.0/getLatestVersion/' . '?' . Http::buildQuery($parameters); diff --git a/plugins/CoreUpdater/Updater.php b/plugins/CoreUpdater/Updater.php index 40f1154309..cfaed0a672 100644 --- a/plugins/CoreUpdater/Updater.php +++ b/plugins/CoreUpdater/Updater.php @@ -75,17 +75,6 @@ class Updater } /** - * @return bool - */ - public function isUpdatingOverHttps() - { - $openSslEnabled = extension_loaded('openssl'); - $usingMethodSupportingHttps = (Http::getTransportMethod() !== 'socket'); - - return $openSslEnabled && $usingMethodSupportingHttps; - } - - /** * Update Piwik codebase by downloading and installing the latest version. * * @param bool $https Whether to use HTTPS if supported of not. If false, will use HTTP. @@ -364,7 +353,7 @@ class Updater $channel = $this->releaseChannels->getActiveReleaseChannel(); $url = $channel->getDownloadUrlWithoutScheme($version); - if ($this->isUpdatingOverHttps() && $https) { + if (Http::isUpdatingOverHttps() && $https) { $url = 'https' . $url; } else { $url = 'http' . $url; diff --git a/plugins/CoreUpdater/tests/Integration/ReleaseChannelTest.php b/plugins/CoreUpdater/tests/Integration/ReleaseChannelTest.php index 476b4e0e5c..ea56a09e2e 100644 --- a/plugins/CoreUpdater/tests/Integration/ReleaseChannelTest.php +++ b/plugins/CoreUpdater/tests/Integration/ReleaseChannelTest.php @@ -60,7 +60,7 @@ class ReleaseChannelTest extends IntegrationTestCase $urlToCheck = $this->channel->getUrlToCheckForLatestAvailableVersion(); - $this->assertStringStartsWith("http://api.matomo.org/1.0/getLatestVersion/?piwik_version=$version&php_version=$phpVersion&mysql_version=$mysqlVersion&release_channel=my_channel&url=$url&trigger=&timezone=", $urlToCheck); + $this->assertStringStartsWith("https://api.matomo.org/1.0/getLatestVersion/?piwik_version=$version&php_version=$phpVersion&mysql_version=$mysqlVersion&release_channel=my_channel&url=$url&trigger=&timezone=", $urlToCheck); } public function test_doesPreferStable() diff --git a/plugins/Installation/lang/en.json b/plugins/Installation/lang/en.json index 3a1a723b9b..cb1d1f5c36 100644 --- a/plugins/Installation/lang/en.json +++ b/plugins/Installation/lang/en.json @@ -136,7 +136,7 @@ "SystemCheckCronArchiveProcessCLI": "Managing processes via CLI", "SystemCheckPhpSetting": "Set up your php.ini file like this to prevent critical errors: %s", "SystemCheckUpdateHttps": "Update over HTTPS", - "SystemCheckUpdateHttpsNotSupported": "Matomo cannot use HTTPS to update, it will fall back to the insecure HTTP update. Check that CURL or allow_url_fopen is supported and that the OpenSSL PHP-extension is installed: https:\/\/matomo.org\/faq\/troubleshooting\/faq_177\/.", + "SystemCheckUpdateHttpsNotSupported": "Matomo cannot use HTTPS to update, it will fall back to the insecure HTTP update. Check that CURL or allow_url_fopen is supported and that the OpenSSL PHP-extension is installed: https:\/\/matomo.org\/faq\/troubleshooting\/faq_177\/. If you like to disable HTTPS please set force_matomo_ssl_request to 0 under general config.", "PhpBinaryCheck" : "64-bit PHP Binary", "PhpBinaryCheckHelp": "32-bit <p>Upgrade to a 64-bit PHP binary by January 2026 to prevent bugs.</p>", "NotSupported": "not supported", @@ -158,6 +158,7 @@ "CannotConnectToDbResolvingExplanation": "This may be a temporary issue, try %1$srefreshing the page%2$s. Please contact your Matomo administrator if the problem persists.", "EmailPrivacyNotice": "Your email address will only be used to send you the newsletter. It is shared with Mad Mimi to do so, but the third-party provider may change. We will not share your email with anyone else or use your it for any other purpose. Unsubscribe at any time. The %1$sprivacy policy%2$s has more info.", "PerformanceSettingsDesc1": "Your Matomo is set up and ready to track and report on your website's traffic. Set up %1$sCLI archiving%2$s if you find it to be slow. This generates reports in the background, rather than on demand.", - "PerformanceSettingsDesc2": "This requires adding a Matomo command to Cron which can't be done automatically by the installer. %1$sRead our FAQ to learn to set it up yourself.%2$s" + "PerformanceSettingsDesc2": "This requires adding a Matomo command to Cron which can't be done automatically by the installer. %1$sRead our FAQ to learn to set it up yourself.%2$s", + "MatomoSslRequestConfigInfo": "The force_matomo_ssl_request in the general config is turned off, we highly recommend switching it on" } } diff --git a/plugins/Marketplace/Api/Client.php b/plugins/Marketplace/Api/Client.php index 953ffbb56b..5e81b6c982 100644 --- a/plugins/Marketplace/Api/Client.php +++ b/plugins/Marketplace/Api/Client.php @@ -8,15 +8,16 @@ */ namespace Piwik\Plugins\Marketplace\Api; +use Exception as PhpException; use Matomo\Cache\Lazy; use Piwik\Common; +use Piwik\Config\GeneralConfig; use Piwik\Container\StaticContainer; use Piwik\Filesystem; use Piwik\Http; use Piwik\Plugin; use Piwik\Plugins\Marketplace\Environment; use Piwik\SettingsServer; -use Exception as PhpException; use Psr\Log\LoggerInterface; /** @@ -325,4 +326,18 @@ class Client return $this->service->getDomain() . $downloadUrl . '?coreVersion=' . $this->environment->getPiwikVersion(); } + /** + * this will return the api.matomo.org through right protocols + * @return string + */ + public static function getApiServiceUrl() + { + $url = GeneralConfig::getConfigValue('api_service_url'); + if (!GeneralConfig::getConfigValue('force_matomo_ssl_request')) { + $url = str_replace('https', 'http', $url); + } + + return $url; + } + } diff --git a/plugins/Marketplace/Controller.php b/plugins/Marketplace/Controller.php index 3436e34b05..dc5c0cc3f3 100644 --- a/plugins/Marketplace/Controller.php +++ b/plugins/Marketplace/Controller.php @@ -8,6 +8,7 @@ namespace Piwik\Plugins\Marketplace; +use Exception; use Piwik\Common; use Piwik\Date; use Piwik\Filesystem; @@ -29,7 +30,6 @@ use Piwik\SettingsPiwik; use Piwik\SettingsServer; use Piwik\Url; use Piwik\View; -use Exception; class Controller extends \Piwik\Plugin\ControllerAdmin { @@ -521,4 +521,5 @@ class Controller extends \Piwik\Plugin\ControllerAdmin return $view; } + } diff --git a/plugins/Marketplace/config/config.php b/plugins/Marketplace/config/config.php index ac6a1bb0df..1ebe26f698 100644 --- a/plugins/Marketplace/config/config.php +++ b/plugins/Marketplace/config/config.php @@ -1,16 +1,16 @@ <?php -use Psr\Container\ContainerInterface; +use Piwik\Config\GeneralConfig; use Piwik\Plugins\Marketplace\Api\Service; use Piwik\Plugins\Marketplace\LicenseKey; +use Psr\Container\ContainerInterface; return array( 'MarketplaceEndpoint' => function (ContainerInterface $c) { - $domain = 'http://plugins.matomo.org'; - $updater = $c->get('Piwik\Plugins\CoreUpdater\Updater'); + $domain = 'https://plugins.matomo.org'; - if ($updater->isUpdatingOverHttps()) { - $domain = str_replace('http://', 'https://', $domain); + if (GeneralConfig::getConfigValue('force_matomo_ssl_request') === 0) { + $domain = str_replace('https://', 'http://', $domain); } return $domain; @@ -28,5 +28,5 @@ return array( $service->authenticate($accessToken); return $service; - } + }, ); diff --git a/plugins/Marketplace/config/test.php b/plugins/Marketplace/config/test.php index 94dba1508e..d302d92446 100644 --- a/plugins/Marketplace/config/test.php +++ b/plugins/Marketplace/config/test.php @@ -1,10 +1,10 @@ <?php -use Psr\Container\ContainerInterface; -use Piwik\Plugins\Marketplace\tests\Framework\Mock\Consumer as MockConsumer; +use Piwik\Plugins\Marketplace\Input\PurchaseType; use Piwik\Plugins\Marketplace\LicenseKey; +use Piwik\Plugins\Marketplace\tests\Framework\Mock\Consumer as MockConsumer; use Piwik\Plugins\Marketplace\tests\Framework\Mock\Service as MockService; -use Piwik\Plugins\Marketplace\Input\PurchaseType; +use Psr\Container\ContainerInterface; return array( 'MarketplaceEndpoint' => function (ContainerInterface $c) { @@ -12,9 +12,8 @@ return array( // it is because someone might have overwritten MarketplaceEndpoit in local config.php and we want // to make sure system tests of marketplace are ran against plugins.piwik.org $domain = 'http://plugins.piwik.org'; - $updater = $c->get('Piwik\Plugins\CoreUpdater\Updater'); - if ($updater->isUpdatingOverHttps()) { + if (\Piwik\Http::isUpdatingOverHttps()) { $domain = str_replace('http://', 'https://', $domain); } diff --git a/plugins/UsersManager/NewsletterSignup.php b/plugins/UsersManager/NewsletterSignup.php index 3e8be85a89..f1d38a31ae 100644 --- a/plugins/UsersManager/NewsletterSignup.php +++ b/plugins/UsersManager/NewsletterSignup.php @@ -10,10 +10,10 @@ namespace Piwik\Plugins\UsersManager; use Exception; -use Piwik\Config; use Piwik\Container\StaticContainer; use Piwik\Http; use Piwik\Option; +use Piwik\Plugins\Marketplace\Api\Client; use Piwik\SettingsPiwik; class NewsletterSignup @@ -28,7 +28,7 @@ class NewsletterSignup return false; } - $url = Config::getInstance()->General['api_service_url']; + $url = Client::getApiServiceUrl(); $url .= '/1.0/subscribeNewsletter/'; $params = array( diff --git a/tests/UI/expected-screenshots/UIIntegrationTest_admin_diagnostics_configfile.png b/tests/UI/expected-screenshots/UIIntegrationTest_admin_diagnostics_configfile.png index b695e8024e..f9724156e1 100644 --- a/tests/UI/expected-screenshots/UIIntegrationTest_admin_diagnostics_configfile.png +++ b/tests/UI/expected-screenshots/UIIntegrationTest_admin_diagnostics_configfile.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2966040ad5b9014d7f9d42597c44977adb3bd8c3905b8ed976af940bb838303 -size 5259775 +oid sha256:5352bb565d46cc2a592f0159393bb05057c249d3d07b9d87fea7ec838cae2b26 +size 5275447 |