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