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:
authordizzy <diosmosis@users.noreply.github.com>2021-02-18 01:55:26 +0300
committerGitHub <noreply@github.com>2021-02-18 01:55:26 +0300
commit715ded1af3cfd7d93f94fe58f5e0ecb8d8b5634c (patch)
tree289ccfb1170cbe6479446a66a0209d898b8c87ea
parent41964121548784f6e15cbe51194cf3b929be7585 (diff)
Allow nonce checks to provide custom required referrer URL. (#17228)
* Allow checking nonce against custom referrer if needed. * Add tests.
-rw-r--r--core/Nonce.php23
-rw-r--r--tests/PHPUnit/Unit/NonceTest.php23
2 files changed, 42 insertions, 4 deletions
diff --git a/core/Nonce.php b/core/Nonce.php
index ef0b09bf21..74aea105d2 100644
--- a/core/Nonce.php
+++ b/core/Nonce.php
@@ -65,9 +65,10 @@ 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.
* @return bool `true` if valid; `false` otherwise.
*/
- public static function verifyNonce($id, $cnonce)
+ public static function verifyNonce($id, $cnonce, $expectedReferrerHost = null)
{
$ns = new SessionNamespace($id);
$nonce = $ns->nonce;
@@ -79,7 +80,10 @@ class Nonce
// validate referrer
$referrer = Url::getReferrer();
- if (!empty($referrer) && !Url::isLocalUrl($referrer)) {
+ if (empty($expectedReferrerHost) && !empty($referrer) && !Url::isLocalUrl($referrer)) {
+ return false;
+ }
+ if (!empty($expectedReferrerHost) && !self::isReferrerHostValid($referrer, $expectedReferrerHost)) {
return false;
}
@@ -95,6 +99,17 @@ class Nonce
return true;
}
+ // public for tests
+ public static function isReferrerHostValid($referrer, $expectedReferrerHost)
+ {
+ if (empty($referrer)) {
+ return false;
+ }
+
+ $referrerHost = Url::getHostFromUrl($referrer);
+ return preg_match('/(^|\.)' . preg_quote($expectedReferrerHost) . '$/i', $referrerHost);
+ }
+
/**
* Force expiration of the current nonce.
*
@@ -169,13 +184,13 @@ class Nonce
* **nonce** query parameter is used.
* @throws \Exception if the nonce is invalid. See {@link verifyNonce()}.
*/
- public static function checkNonce($nonceName, $nonce = null)
+ public static function checkNonce($nonceName, $nonce = null, $expectedReferrerHost = null)
{
if ($nonce === null) {
$nonce = Common::getRequestVar('nonce', null, 'string');
}
- if (!self::verifyNonce($nonceName, $nonce)) {
+ if (!self::verifyNonce($nonceName, $nonce, $expectedReferrerHost)) {
throw new \Exception(Piwik::translate('General_ExceptionNonceMismatch'));
}
diff --git a/tests/PHPUnit/Unit/NonceTest.php b/tests/PHPUnit/Unit/NonceTest.php
index 9020257f31..00d4393b69 100644
--- a/tests/PHPUnit/Unit/NonceTest.php
+++ b/tests/PHPUnit/Unit/NonceTest.php
@@ -42,4 +42,27 @@ class NonceTest extends \PHPUnit\Framework\TestCase
Config::getInstance()->General['trusted_hosts'] = array('example.com');
$this->assertEquals($expected, Nonce::getAcceptableOrigins(), $host);
}
+
+ /**
+ * @dataProvider getTestDataForIsReferrerHostValid
+ * @group Core
+ */
+ public function test_isReferrerHostValid($referrer, $expectedHost, $expectedResult)
+ {
+ $result = Nonce::isReferrerHostValid($referrer, $expectedHost);
+ $this->assertEquals($expectedResult, $result);
+ }
+
+ public function getTestDataForIsReferrerHostValid()
+ {
+ return [
+ ['http://referrer.com', 'someotherreferrer.com', false],
+ ['http://referrer.com/referrer/path', 'referrer.com', true],
+ ['http://areferrer.com', 'referrer.com', false],
+ ['http://sub.referrer.com', 'referrer.com', true],
+ ['http://sub.referrer.com', 'sub.referrer.com', true],
+ ['http://sub.referrer.com', 'a.sub.referrer.com', false],
+ ['http://sub.referrer.com', 'sub2.referrer.com', false],
+ ];
+ }
}