Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/Nonce.php58
-rw-r--r--plugins/Login/Controller.php51
-rw-r--r--plugins/Login/lang/en.json7
-rw-r--r--plugins/TwoFactorAuth/Controller.php8
4 files changed, 70 insertions, 54 deletions
diff --git a/core/Nonce.php b/core/Nonce.php
index 74aea105d2..b4ae2a7a5c 100644
--- a/core/Nonce.php
+++ b/core/Nonce.php
@@ -65,38 +65,80 @@ class Nonce
*
* @param string $id The nonce's unique ID. See {@link getNonce()}.
* @param string $cnonce Nonce sent from client.
- * @param string $expectedReferrerHost The expected referrer host for the HTTP referrer URL.
+ * @param null|string $expectedReferrerHost The expected referrer host for the HTTP referrer URL.
* @return bool `true` if valid; `false` otherwise.
*/
public static function verifyNonce($id, $cnonce, $expectedReferrerHost = null)
{
+ // load error with message function.
+ $error = self::verifyNonceWithErrorMessage($id, $cnonce, $expectedReferrerHost);
+ return $error === "";
+ }
+
+ /**
+ * Returns error message
+ *
+ * A nonce is valid if it matches the current nonce and if the current nonce
+ * has not expired.
+ *
+ * The request is valid if the referrer is a local URL (see {@link Url::isLocalUrl()})
+ * and if the HTTP origin is valid (see {@link getAcceptableOrigins()}).
+ *
+ * @param string $id The nonce's unique ID. See {@link getNonce()}.
+ * @param string $cnonce Nonce sent from client.
+ * @param null $expectedReferrerHost The expected referrer host for the HTTP referrer URL.
+ * @return string if empty is valid otherwise return error message
+ */
+ public static function verifyNonceWithErrorMessage($id, $cnonce, $expectedReferrerHost = null)
+ {
$ns = new SessionNamespace($id);
$nonce = $ns->nonce;
+ $additionalErrors = '';
+
+ // The Session cookie is set to a secure cookie, when SSL is mis-configured, it can cause the PHP session cookie ID to change on each page view.
+ // Indicate to user how to solve this particular use case by forcing secure connections.
+ if (Url::isSecureConnectionAssumedByPiwikButNotForcedYet()) {
+ $additionalErrors = '<br/><br/>' . Piwik::translate('Login_InvalidNonceSSLMisconfigured',
+ array(
+ '<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/how-to/faq_91/">',
+ '</a>',
+ 'config/config.ini.php',
+ '<pre>force_ssl=1</pre>',
+ '<pre>[General]</pre>',
+ )
+ );
+ }
+
// validate token
if (empty($cnonce) || $cnonce !== $nonce) {
- return false;
+ return Piwik::translate('Login_InvalidNonceToken');
}
// validate referrer
$referrer = Url::getReferrer();
if (empty($expectedReferrerHost) && !empty($referrer) && !Url::isLocalUrl($referrer)) {
- return false;
+ return Piwik::translate('Login_InvalidNonceReferrer', array(
+ '<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/how-to-install/#faq_98">',
+ '</a>'
+ )) . $additionalErrors;
}
+
+ //referrer is different expected host
if (!empty($expectedReferrerHost) && !self::isReferrerHostValid($referrer, $expectedReferrerHost)) {
- return false;
+ return Piwik::translate('Login_InvalidNonceUnexpectedReferrer') . $additionalErrors;
}
// validate origin
$origin = self::getOrigin();
if (!empty($origin) &&
- ($origin == 'null'
- || !in_array($origin, self::getAcceptableOrigins()))
+ ($origin == 'null'
+ || !in_array($origin, self::getAcceptableOrigins()))
) {
- return false;
+ return Piwik::translate('Login_InvalidNonceOrigin') . $additionalErrors;
}
- return true;
+ return '';
}
// public for tests
diff --git a/plugins/Login/Controller.php b/plugins/Login/Controller.php
index a1daed412e..b13f3f8231 100644
--- a/plugins/Login/Controller.php
+++ b/plugins/Login/Controller.php
@@ -133,7 +133,10 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$form = new FormLogin();
if ($form->validate()) {
$nonce = $form->getSubmitValue('form_nonce');
- if (Nonce::verifyNonce('Login.login', $nonce)) {
+ $messageNoAccess = Nonce::verifyNonceWithErrorMessage('Login.login', $nonce, null);
+
+ // validate if there is error message
+ if ($messageNoAccess === "") {
$loginOrEmail = $form->getSubmitValue('form_login');
$login = $this->getLoginFromLoginOrEmail($loginOrEmail);
@@ -143,11 +146,9 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
} catch (Exception $e) {
$messageNoAccess = $e->getMessage();
}
- } else {
- $messageNoAccess = $this->getMessageExceptionNoAccess();
}
}
-
+
if ($messageNoAccess) {
http_response_code(403);
}
@@ -212,8 +213,9 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
if ($password) {
$password = Common::unsanitizeInputValue($password);
}
- if (!Nonce::verifyNonce($nonceKey, $nonce)) {
- $messageNoAccess = $this->getMessageExceptionNoAccess();
+ $errorMessage = Nonce::verifyNonceWithErrorMessage($nonceKey, $nonce);
+ if ($errorMessage !== "") {
+ $messageNoAccess = $errorMessage;
} elseif ($this->passwordVerify->isPasswordCorrect(Piwik::getCurrentUserLogin(), $password)) {
$this->passwordVerify->setPasswordVerifiedCorrectly();
return;
@@ -349,38 +351,6 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
Url::redirectToUrl($urlToRedirect);
}
- protected function getMessageExceptionNoAccess()
- {
- $message = Piwik::translate('Login_InvalidNonceOrHeadersOrReferrer', array('<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/how-to-install/#faq_98">', '</a>'));
-
- $message .= $this->getMessageExceptionNoAccessWhenInsecureConnectionMayBeUsed();
-
- return $message;
- }
-
- /**
- * The Session cookie is set to a secure cookie, when SSL is mis-configured, it can cause the PHP session cookie ID to change on each page view.
- * Indicate to user how to solve this particular use case by forcing secure connections.
- *
- * @return string
- */
- protected function getMessageExceptionNoAccessWhenInsecureConnectionMayBeUsed()
- {
- $message = '';
- if(Url::isSecureConnectionAssumedByPiwikButNotForcedYet()) {
- $message = '<br/><br/>' . Piwik::translate('Login_InvalidNonceSSLMisconfigured',
- array(
- '<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/how-to/faq_91/">',
- '</a>',
- 'config/config.ini.php',
- '<pre>force_ssl=1</pre>',
- '<pre>[General]</pre>',
- )
- );
- }
- return $message;
- }
-
/**
* Reset password action. Stores new password as hash and sends email
* to confirm use.
@@ -394,13 +364,14 @@ class Controller extends \Piwik\Plugin\ControllerAdmin
$form = new FormResetPassword();
if ($form->validate()) {
$nonce = $form->getSubmitValue('form_nonce');
- if (Nonce::verifyNonce('Login.login', $nonce)) {
+ $errorMessage = Nonce::verifyNonceWithErrorMessage('Login.login', $nonce);
+ if ($errorMessage === "") {
$formErrors = $this->resetPasswordFirstStep($form);
if (empty($formErrors)) {
$infoMessage = Piwik::translate('Login_ConfirmationLinkSent');
}
} else {
- $formErrors = array($this->getMessageExceptionNoAccess());
+ $formErrors = array($errorMessage);
}
} else {
// if invalid, display error
diff --git a/plugins/Login/lang/en.json b/plugins/Login/lang/en.json
index 92597b4a0c..361c2c1b77 100644
--- a/plugins/Login/lang/en.json
+++ b/plugins/Login/lang/en.json
@@ -5,7 +5,10 @@
"ContactAdmin": "Possible reason: your host may have disabled the mail() function. <br \/>Please contact your Matomo administrator.",
"ExceptionInvalidSuperUserAccessAuthenticationMethod": "A user with Super User access cannot be authenticated using the '%s' mechanism.",
"ExceptionPasswordMD5HashExpected": "The password parameter is expected to be a MD5 hash of the password.",
- "InvalidNonceOrHeadersOrReferrer": "Form security failed. Please reload the form and check that your cookies are enabled. If you use a proxy server, you must %1$s configure Matomo to accept the proxy header%2$s that forwards the Host header. Also, check that your Referrer header is sent correctly.",
+ "InvalidNonceToken": "Form security failed, token miss match. Please reload the form and check that your cookies are enabled.",
+ "InvalidNonceReferrer": "Form security failed, invalid referrer header. If you use a proxy server, you must %1$s configure Matomo to accept the proxy header %2$s that forwards the Host header. Also, check that your Referrer header is sent correctly and If you previously connected using https, please ensure you are connecting over a secure (SSL/TLS) connection and try again.",
+ "InvalidNonceUnexpectedReferrer" : "Form security failed, the referrer header is different from the expected referrer header, check that your Referrer header is sent correctly.",
+ "InvalidNonceOrigin": "Form security failed, invalid origin. If you previously connected using https, please ensure you are connecting over a secure (SSL/TLS) connection and try again.",
"InvalidNonceSSLMisconfigured": "Also, you may %1$s force Matomo to use a secure connection%2$s: in your config file %3$s set %4$s below section %5$s",
"InvalidOrExpiredToken": "Token is invalid or has expired.",
"InvalidUsernameEmail": "Invalid username or e-mail address.",
@@ -53,4 +56,4 @@
"SuspiciousLoginAttemptsInLastHourEmail5": "Additionally, if your Matomo has a limited set of users or IPs through which users will access it, it may be beneficial to setup a IP address allowlist. %1$sRead our docs for more information.%2$s",
"LoginNotAllowedBecauseUserLoginBlocked": "Login functionality is temporarily disabled since we've a suspicious amount of failed login attempts in the last hour."
}
-} \ No newline at end of file
+}
diff --git a/plugins/TwoFactorAuth/Controller.php b/plugins/TwoFactorAuth/Controller.php
index daa97f21eb..e7936b5202 100644
--- a/plugins/TwoFactorAuth/Controller.php
+++ b/plugins/TwoFactorAuth/Controller.php
@@ -83,7 +83,8 @@ class Controller extends \Piwik\Plugin\Controller
$form->removeAttribute('action'); // remove action attribute, otherwise hash part will be lost
if ($form->validate()) {
$nonce = $form->getSubmitValue('form_nonce');
- if ($nonce && Nonce::verifyNonce(self::LOGIN_2FA_NONCE, $nonce) && $form->validate()) {
+ $messageNoAccess = Nonce::verifyNonceWithErrorMessage(self::LOGIN_2FA_NONCE, $nonce);
+ if ($nonce && $messageNoAccess === "" && $form->validate()) {
$authCode = $form->getSubmitValue('form_authcode');
if ($authCode && is_string($authCode)) {
$authCode = str_replace('-', '', $authCode);
@@ -106,8 +107,6 @@ class Controller extends \Piwik\Plugin\Controller
// ignore error eg if login plugin is disabled
}
}
- } else {
- $messageNoAccess = Piwik::translate('Login_InvalidNonceOrHeadersOrReferrer', array('<a target="_blank" rel="noreferrer noopener" href="https://matomo.org/faq/how-to-install/#faq_98">', '</a>'));
}
}
$superUsers = Request::processRequest('UsersManager.getUsersHavingSuperUserAccess', [], []);
@@ -288,7 +287,8 @@ class Controller extends \Piwik\Plugin\Controller
$this->validator->check2FaEnabled();
$regenerateNonce = Common::getRequestVar('regenerateNonce', '', 'string', $_POST);
- $postedValidNonce = !empty($regenerateNonce) && Nonce::verifyNonce(self::REGENERATE_CODES_2FA_NONCE, $regenerateNonce);
+ $postedValidNonce = !empty($regenerateNonce) && Nonce::verifyNonce(self::REGENERATE_CODES_2FA_NONCE,
+ $regenerateNonce);
$regenerateSuccess = false;
$regenerateError = false;