diff --git a/src/Utils.php b/src/Utils.php index deaafa81..0ac77e81 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -116,7 +116,7 @@ public static function validateHmac(array $params, string $secret): bool return hash_equals( $params['hmac'], - hash_hmac('sha256', self::buildQueryString($params), $secret) + hash_hmac('sha256', urldecode(self::buildQueryString($params)), $secret) ); } diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index bfc3364b..d5310c95 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php @@ -147,7 +147,7 @@ public function testValidHmac() $url = 'https://123456.ngrok.io/auth/shopify/callback?code=0907a61c0c8d55e99db179b68161bc00&&shop=some-shop.myshopify.com&state=0.6784241404160823×tamp=1337178173'; $params = Utils::getQueryParams($url); $secret = 'test-secret'; - $params['hmac'] = hash_hmac('sha256', http_build_query($params), $secret); + $params['hmac'] = hash_hmac('sha256', urldecode(http_build_query($params)), $secret); $this->assertEquals(true, Utils::validateHmac( $params, @@ -161,7 +161,7 @@ public function testInvalidHmac() $url = 'https://123456.ngrok.io/auth/shopify/callback?code=0907a61c0c8d55e99db179b68161bc00&&shop=some-shop.myshopify.com&state=0.6784241404160823×tamp=1337178173'; $params = Utils::getQueryParams($url); $secret = 'test-secret'; - $params['hmac'] = hash_hmac('sha256', http_build_query($params), $secret); + $params['hmac'] = hash_hmac('sha256', urldecode(http_build_query($params)), $secret); // Check with a wrong secret $this->assertEquals(false, Utils::validateHmac( @@ -177,6 +177,31 @@ public function testInvalidHmac() )); } + public function testHmacOfEncodedUriComponents() + { + $state = base64_encode(json_encode(['id' => '0123456789', 'for' => 'some-shop'])); + // phpcs:ignore + $url = 'https://123456.ngrok.io/auth/shopify/callback?code=0907a61c0c8d55e99db179b68161bc00&state=' . $state . '&shop=some-shop.myshopify.com×tamp=1337178173'; + $params = Utils::getQueryParams($url); + $secret = 'test-secret'; + + $paramsWrong = $params + ['hmac' => hash_hmac('sha256', http_build_query($params), $secret)]; + $paramsRight = $params + ['hmac' => hash_hmac('sha256', urldecode(http_build_query($params)), $secret)]; + + // Check with the encoded version of the URI (wrong) + $this->assertEquals(false, Utils::validateHmac( + $paramsWrong, + $secret + )); + + + // Check with the decoded version of the URI + $this->assertEquals(true, Utils::validateHmac( + $paramsRight, + $secret + )); + } + public function testGetValidQueryParams() { $params = [