]> BookStack Code Mirror - bookstack/blob - app/Util/SsrUrlValidator.php
0b3a6a31de9a3a79823c2c3c7a129dc251ab531b
[bookstack] / app / Util / SsrUrlValidator.php
1 <?php
2
3 namespace BookStack\Util;
4
5 use BookStack\Exceptions\HttpFetchException;
6
7 class SsrUrlValidator
8 {
9     protected string $config;
10
11     public function __construct(string $config = null)
12     {
13         $this->config = $config ?? config('app.ssr_hosts') ?? '';
14     }
15
16     /**
17      * @throws HttpFetchException
18      */
19     public function ensureAllowed(string $url): void
20     {
21         if (!$this->allowed($url)) {
22             throw new HttpFetchException(trans('errors.http_ssr_url_no_match'));
23         }
24     }
25
26     /**
27      * Check if the given URL is allowed by the configured SSR host values.
28      */
29     public function allowed(string $url): bool
30     {
31         $allowed = $this->getHostPatterns();
32
33         foreach ($allowed as $pattern) {
34             if ($this->urlMatchesPattern($url, $pattern)) {
35                 return true;
36             }
37         }
38
39         return false;
40     }
41
42     protected function urlMatchesPattern($url, $pattern): bool
43     {
44         $pattern = rtrim(trim($pattern), '/');
45         $url = trim($url);
46
47         if (empty($pattern) || empty($url)) {
48             return false;
49         }
50
51         $quoted = preg_quote($pattern, '/');
52         $regexPattern = str_replace('\*', '.*', $quoted);
53
54         return preg_match('/^' . $regexPattern . '($|\/.*$|#.*$)/i', $url);
55     }
56
57     /**
58      * @return string[]
59      */
60     protected function getHostPatterns(): array
61     {
62         return explode(' ', strtolower($this->config));
63     }
64 }