PDF converter * distributed under the OSL-3.0 License * * @package Html2pdf * @author Laurent MINGUET * @copyright 2025 Laurent MINGUET */ namespace Spipu\Html2Pdf\Security; use Spipu\Html2Pdf\Exception\HtmlParsingException; class Security implements SecurityInterface { /** * @var string[] */ protected $allowedSchemes = ['file', 'http', 'https']; /** * @var string[] */ protected $allowedHosts = []; /** * @var bool */ private $checkAllowedHosts = true; /** * @param string $path * @return void * @throws HtmlParsingException */ public function checkValidPath(string $path): void { $path = trim(strtolower($path)); if (!$this->checkValidPathScheme($path)) { throw new HtmlParsingException('Unauthorized path scheme'); } if ($this->checkAllowedHosts && !$this->checkValidPathHost($path)) { throw new HtmlParsingException('Unauthorized path host on ' . $path . ' => ' . implode('|', $this->allowedHosts)); } } /** * @param string $path * @return bool */ private function checkValidPathScheme(string $path): bool { $scheme = parse_url($path, PHP_URL_SCHEME); if ($scheme === null) { return true; } if (in_array($scheme, $this->allowedSchemes)) { return true; } // for local file on windows if (strlen($scheme) === 1 && preg_match('/^[a-z]$/i', $scheme)) { return true; } return false; } /** * @param string $path * @return bool */ private function checkValidPathHost(string $path): bool { $scheme = parse_url($path, PHP_URL_SCHEME); $host = parse_url($path, PHP_URL_HOST); // If it is a local file => no host if ( $scheme === null || $scheme === 'file' || (strlen($scheme) === 1 && preg_match('/^[a-z]$/i', $scheme)) ) { return true; } return in_array($host, $this->allowedHosts); } /** * @param string $host * @return void */ public function addAllowedHost(string $host): void { $host = trim(strtolower($host)); if (!in_array($host, $this->allowedHosts)) { $this->allowedHosts[] = $host; } } /** * @return void */ public function resetAllowedHosts(): void { $this->allowedHosts = []; } /** * @return void */ public function disableCheckAllowedHosts(): void { $this->checkAllowedHosts = false; } }