Skip to content

Commit bde92b7

Browse files
committed
SignUrl: Fix verify URL with only _debug query
1 parent 7aea6cc commit bde92b7

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

src/Plugin/SignedUrl.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ public function verifyUrl(string $url, bool $allowRedirect = false): array
174174
// Note: Not parsed by parse_str() to prevent broke URL (repeated arguments like `?same_arg=1&same_arg=2`)
175175
$query = $parsedUrl['query'] ?? '';
176176
if (preg_match(
177-
'/(?<token_key>[?&]' . self::URL_QUERY_TOKEN_KEY . '=)(?<token>[^&]+)(?:$|(?<remaining>&.*$))/D',
177+
'/(?<token_key>(?:^|&|^&)' . self::URL_QUERY_TOKEN_KEY . '=)(?<token>[^&]+)(?:$|(?<remaining>&.*$))/D',
178178
$query,
179179
$matches,
180180
PREG_OFFSET_CAPTURE
@@ -200,7 +200,9 @@ public function verifyUrl(string $url, bool $allowRedirect = false): array
200200
}
201201

202202
$parsedUrl = $this->normalizeUrl($parsedUrl);
203-
$signedUrl = $this->buildUrl(['query' => substr($query, 0, $tokenOffset)] + $parsedUrl);
203+
$signedUrl = $this->buildUrl(
204+
['query' => $tokenOffset > 0 ? substr($query, 0, $tokenOffset) : null] + $parsedUrl
205+
);
204206

205207
if ($signedUrl !== $allowedUrl) {
206208
throw new SignedUrlVerificationException('URL doesn\'t match signed URL');

tests/Plugin/SignUrlTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,24 @@ public function testVerifyToken(): void
9191
}
9292

9393
public function testVerifyUrl(): void
94+
{
95+
$audience = 'test.' . __FUNCTION__;
96+
$timestamp = 1600000000;
97+
$url = 'https://host.tld/path';
98+
99+
$plugin = new SignedUrl(self::KEY_HS256, 'HS256', $audience);
100+
$plugin->setTimestamp($timestamp);
101+
$tokenUrl = $plugin->signUrl($url, 1600000600);
102+
103+
$plugin = new SignedUrl(self::KEY_HS256, 'HS256', $audience);
104+
$plugin->setTimestamp($timestamp);
105+
JWT::$timestamp = $timestamp;
106+
$parsed = $plugin->verifyUrl($tokenUrl);
107+
$expected = [['get'], 0, 1, 1600000600];
108+
Assert::equal($expected, $parsed);
109+
}
110+
111+
public function testVerifyUrlQuery(): void
94112
{
95113
$audience = 'test.' . __FUNCTION__;
96114
$timestamp = 1600000000;

0 commit comments

Comments
 (0)