SSR: Updated allow list handling & covered webhook usage

- Covered webhook SSR allow list useage via test.
- Updated allow list handling to use trailing slash, or hash, or end of
  line as late anchor for better handling for hosts (prevent .co.uk
passing for .co domain host)
This commit is contained in:
Dan Brown 2023-08-26 20:13:37 +01:00
parent c324ad928d
commit 903895814a
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 19 additions and 2 deletions

View File

@ -41,7 +41,7 @@ class SsrUrlValidator
protected function urlMatchesPattern($url, $pattern): bool protected function urlMatchesPattern($url, $pattern): bool
{ {
$pattern = trim($pattern); $pattern = rtrim(trim($pattern), '/');
$url = trim($url); $url = trim($url);
if (empty($pattern) || empty($url)) { if (empty($pattern) || empty($url)) {
@ -51,7 +51,7 @@ class SsrUrlValidator
$quoted = preg_quote($pattern, '/'); $quoted = preg_quote($pattern, '/');
$regexPattern = str_replace('\*', '.*', $quoted); $regexPattern = str_replace('\*', '.*', $quoted);
return preg_match('/^' . $regexPattern . '.*$/i', $url); return preg_match('/^' . $regexPattern . '($|\/.*$|#.*$)/i', $url);
} }
/** /**

View File

@ -101,6 +101,20 @@ class WebhookCallTest extends TestCase
$this->assertNotNull($webhook->last_errored_at); $this->assertNotNull($webhook->last_errored_at);
} }
public function test_webhook_uses_ssr_hosts_option_if_set()
{
config()->set('app.ssr_hosts', 'https://*.example.com');
$http = Http::fake();
$webhook = $this->newWebhook(['active' => true, 'endpoint' => 'https://wh.example.co.uk'], ['all']);
$this->runEvent(ActivityType::ROLE_CREATE);
$http->assertNothingSent();
$webhook->refresh();
$this->assertEquals('The URL does not match the configured allowed SSR hosts', $webhook->last_error);
$this->assertNotNull($webhook->last_errored_at);
}
public function test_webhook_call_data_format() public function test_webhook_call_data_format()
{ {
Http::fake([ Http::fake([

View File

@ -25,6 +25,9 @@ class SsrUrlValidatorTest extends TestCase
['config' => 'https://*.example.com', 'url' => 'https://test.example.com', 'result' => true], ['config' => 'https://*.example.com', 'url' => 'https://test.example.com', 'result' => true],
['config' => '*//example.com', 'url' => 'https://example.com', 'result' => true], ['config' => '*//example.com', 'url' => 'https://example.com', 'result' => true],
['config' => '*//example.com', 'url' => 'http://example.com', 'result' => true], ['config' => '*//example.com', 'url' => 'http://example.com', 'result' => true],
['config' => '*//example.co', 'url' => 'http://example.co.uk', 'result' => false],
['config' => '*//example.co/bookstack', 'url' => 'https://example.co/bookstack/a/path', 'result' => true],
['config' => '*//example.co*', 'url' => 'https://example.co.uk/bookstack/a/path', 'result' => true],
['config' => 'https://example.com', 'url' => 'https://example.com/a/b/c?test=cat', 'result' => true], ['config' => 'https://example.com', 'url' => 'https://example.com/a/b/c?test=cat', 'result' => true],
['config' => 'https://example.com', 'url' => 'https://example.co.uk', 'result' => false], ['config' => 'https://example.com', 'url' => 'https://example.co.uk', 'result' => false],