diff --git a/Diagnostic/CurlVersionCheck.php b/Diagnostic/CurlVersionCheck.php new file mode 100644 index 0000000..3526eee --- /dev/null +++ b/Diagnostic/CurlVersionCheck.php @@ -0,0 +1,110 @@ +logger = $logger; + $this->label = "curl version check"; + $this->lazyCache = $lazyCache; + } + + + /** + * @return DiagnosticResult[] + */ + public function execute() + { + if (!extension_loaded('curl')) { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_INFORMATIONAL, + "Your PHP setup doesn't use curl, so there is nothing to check" + )]; + } + $version = curl_version()["version"]; + + $url = "https://curl.se/docs/vuln.pm"; + $timeout = self::SOCKET_TIMEOUT; + try { + $response = $this->lazyCache->fetch(self::CACHEID); + if (!$response) { + $response = Http::sendHttpRequest($url, $timeout); + $this->lazyCache->save(self::CACHEID, $response, 60 * 60 * 24 * 7); + } + $vulns = []; + foreach (explode("\n", $response) as $line) { + $line = trim($line); + if (strpos($line, "#") === 0 || strpos($line, "@") === 0 || strpos($line, ")") === 0) { + continue; + } + $line = str_replace('"', "", $line); + $cols = explode("|", $line); + $startVersion = $cols[1]; + $endVersion = $cols[2]; + $URL = htmlspecialchars($cols[0], ENT_QUOTES, 'UTF-8'); + $CVE = htmlspecialchars($cols[4], ENT_QUOTES, 'UTF-8'); + if ( + version_compare($version, $startVersion, ">=") && + version_compare($version, $endVersion, "<=") + ) { + $vulns[] = "$CVE"; + } + } + if (count($vulns) > 0) { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_ERROR, + "Your curl version might be vulnerable against this vulnerabilities + (unless the distributor of your curl binary is backporting security patches): " + . join(", ", $vulns) + )]; + } else { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_OK, + "It seems like there are no known vulnerabilities in your curl version" + )]; + } + } catch (\Exception $e) { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_INFORMATIONAL, + "Matomo could not check if your curl version has vulnerabilities" + )]; + } + + + } +} diff --git a/Diagnostic/DatabaseVersionCheck.php b/Diagnostic/DatabaseVersionCheck.php index c4a76eb..3094bc7 100644 --- a/Diagnostic/DatabaseVersionCheck.php +++ b/Diagnostic/DatabaseVersionCheck.php @@ -8,15 +8,13 @@ namespace Piwik\Plugins\DiagnosticsExtended\Diagnostic; +use Piwik\Date; use Piwik\Db; use Piwik\Http; -use Piwik\Date; use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResultItem; -use Piwik\Plugins\DiagnosticsExtended\Diagnostic\IniSettings\IniSetting; use Psr\Log\LoggerInterface; -use function DI\factory; class DatabaseVersionCheck implements Diagnostic { diff --git a/Diagnostic/ExampleCheck.php b/Diagnostic/ExampleCheck.php index d619a7d..1d847f3 100644 --- a/Diagnostic/ExampleCheck.php +++ b/Diagnostic/ExampleCheck.php @@ -27,9 +27,11 @@ class ExampleCheck implements Diagnostic public function execute() { - $result=new DiagnosticResult("label"); - $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_ERROR,"a")); - $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_OK,"b")); + $result = new DiagnosticResult("label"); + $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_ERROR, "error")); + $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_WARNING, "warning")); + $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_OK, "okay")); + $result->addItem(new DiagnosticResultItem(DiagnosticResult::STATUS_INFORMATIONAL, "info")); return array($result); } diff --git a/Diagnostic/GzipMatomoJsCheck.php b/Diagnostic/GzipMatomoJsCheck.php index 81e086f..c0ddd7c 100644 --- a/Diagnostic/GzipMatomoJsCheck.php +++ b/Diagnostic/GzipMatomoJsCheck.php @@ -8,17 +8,13 @@ namespace Piwik\Plugins\DiagnosticsExtended\Diagnostic; -use Piwik\Db; use Piwik\Http; -use Piwik\Date; use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResultItem; -use Piwik\Plugins\DiagnosticsExtended\Diagnostic\IniSettings\IniSetting; use Piwik\SettingsPiwik; use Piwik\Tracker\TrackerCodeGenerator; use Psr\Log\LoggerInterface; -use function DI\factory; class GzipMatomoJsCheck implements Diagnostic { diff --git a/Diagnostic/OpensslVersionCheck.php b/Diagnostic/OpensslVersionCheck.php new file mode 100644 index 0000000..9da8cf7 --- /dev/null +++ b/Diagnostic/OpensslVersionCheck.php @@ -0,0 +1,88 @@ +logger = $logger; + $this->label = "OpenSSL version check"; + } + + /** + * @return DiagnosticResult + */ + public function noOpenSSL() + { + return DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_INFORMATIONAL, + "Your PHP setup doesn't use OpenSSL or curl, so there is nothing to check" + ); + } + + + /** + * @return DiagnosticResult[] + */ + public function execute() + { + if (!extension_loaded("curl") || !extension_loaded('openssl')) { + return [$this->noOpenSSL()]; + } + $version = curl_version()["ssl_version"]; + if (strpos($version, "OpenSSL/") !== 0) { + return [$this->noOpenSSL()]; + } + $versionPart = substr($version, 8, 5); + $letterPart = substr($version, 13, 1); + if ( + version_compare($versionPart, self::MINIMUM_VERSION, "<") + || ( + version_compare($versionPart, self::MINIMUM_VERSION, "=") + && ord($letterPart) < ord(self::MINIMUM_VERSION_LETTER) + ) + ) { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_WARNING, + "Your OpenSSL version ($version) is pretty old. + Check if there are known vulnerabilities for it and update it if necessary." + )]; + } else { + return [DiagnosticResult::singleResult( + $this->label, + DiagnosticResult::STATUS_INFORMATIONAL, + "Your OpenSSL version ($version) is not really old. + Nevertheless, check if there are known vulnerabilities for it and update it if necessary." + )]; + } + } +} diff --git a/Diagnostic/PhpUserCheck.php b/Diagnostic/PhpUserCheck.php new file mode 100644 index 0000000..fb01cc2 --- /dev/null +++ b/Diagnostic/PhpUserCheck.php @@ -0,0 +1,48 @@ +logger = $logger; + } + + /** + * @return DiagnosticResult[] + */ + public function execute() + { + if (SettingsServer::isWindows()) { + return []; + } + if (posix_getuid() === 0) { + return [DiagnosticResult::singleResult( + "php running as root", + DiagnosticResult::STATUS_WARNING, + "PHP seems to be running as root. Unless you are using Matomo inside a docker container + you should check your setup." + )]; + } + return []; + } + + +} diff --git a/Diagnostic/PhpVersionCheck.php b/Diagnostic/PhpVersionCheck.php index e2e97e0..24fd919 100644 --- a/Diagnostic/PhpVersionCheck.php +++ b/Diagnostic/PhpVersionCheck.php @@ -8,14 +8,12 @@ namespace Piwik\Plugins\DiagnosticsExtended\Diagnostic; -use Piwik\Http; use Piwik\Date; +use Piwik\Http; use Piwik\Plugins\Diagnostics\Diagnostic\Diagnostic; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult; use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResultItem; -use Piwik\Plugins\DiagnosticsExtended\Diagnostic\IniSettings\IniSetting; use Psr\Log\LoggerInterface; -use function DI\factory; class PhpVersionCheck implements Diagnostic { diff --git a/config/config.php b/config/config.php index 42f584c..26c8bc9 100644 --- a/config/config.php +++ b/config/config.php @@ -15,6 +15,9 @@ return [ DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\PhpVersionCheck'), DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\DatabaseVersionCheck'), DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\GzipMatomoJsCheck'), + DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\CurlVersionCheck'), + DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\OpensslVersionCheck'), + DI\get('\Piwik\Plugins\DiagnosticsExtended\Diagnostic\PhpUserCheck'), ]), ];