]> BookStack Code Mirror - bookstack/commitdiff
SSR: Updated allow list handling & covered webhook usage
authorDan Brown <redacted>
Sat, 26 Aug 2023 19:13:37 +0000 (20:13 +0100)
committerDan Brown <redacted>
Sat, 26 Aug 2023 19:13:37 +0000 (20:13 +0100)
- 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)

app/Util/SsrUrlValidator.php
tests/Actions/WebhookCallTest.php
tests/Unit/SsrUrlValidatorTest.php

index 722a45f7b6c13109cb7245fbcbd77d2866bc8786..0b3a6a31de9a3a79823c2c3c7a129dc251ab531b 100644 (file)
@@ -41,7 +41,7 @@ class SsrUrlValidator
 
     protected function urlMatchesPattern($url, $pattern): bool
     {
-        $pattern = trim($pattern);
+        $pattern = rtrim(trim($pattern), '/');
         $url = trim($url);
 
         if (empty($pattern) || empty($url)) {
@@ -51,7 +51,7 @@ class SsrUrlValidator
         $quoted = preg_quote($pattern, '/');
         $regexPattern = str_replace('\*', '.*', $quoted);
 
-        return preg_match('/^' . $regexPattern . '.*$/i', $url);
+        return preg_match('/^' . $regexPattern . '($|\/.*$|#.*$)/i', $url);
     }
 
     /**
index fc49a524eef2c40e99b5206cca6b241c50518c47..0746aa3a1b2e87d1c22e424517530012bb55003d 100644 (file)
@@ -101,6 +101,20 @@ class WebhookCallTest extends TestCase
         $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()
     {
         Http::fake([
index 1443eedd7fdebd1a5d08a56df20108996a05632e..8fb538916aa86f58a3c1ab06e5ec9ea48a5326bd 100644 (file)
@@ -25,6 +25,9 @@ class SsrUrlValidatorTest extends TestCase
             ['config' => 'https://*.example.com', 'url' => 'https://test.example.com', 'result' => true],
             ['config' => '*//example.com', 'url' => 'https://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.co.uk', 'result' => false],