From e499968818f758c4afbc85b4e2fed23f3214bbef Mon Sep 17 00:00:00 2001 From: Thorsten Rinne Date: Sat, 14 Dec 2024 12:07:48 +0100 Subject: [PATCH] fix: more hadening of rewrite base path check, closes #3281 --- phpmyfaq/assets/templates/setup/update.twig | 6 +++ .../Controller/Frontend/SetupController.php | 20 ++++++++-- phpmyfaq/src/phpMyFAQ/Setup/Installer.php | 34 +++++++++++++++++ phpmyfaq/src/phpMyFAQ/Setup/Update.php | 38 +++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) diff --git a/phpmyfaq/assets/templates/setup/update.twig b/phpmyfaq/assets/templates/setup/update.twig index ea08e63ec2..2f4aaf337b 100644 --- a/phpmyfaq/assets/templates/setup/update.twig +++ b/phpmyfaq/assets/templates/setup/update.twig @@ -56,6 +56,12 @@ {{ include('./setup/update/step' ~ currentStep ~ '.twig') }} + {% if checkBasicError %} + + {% endif %} + diff --git a/phpmyfaq/src/phpMyFAQ/Controller/Frontend/SetupController.php b/phpmyfaq/src/phpMyFAQ/Controller/Frontend/SetupController.php index 896b7847c1..86aab283ae 100644 --- a/phpmyfaq/src/phpMyFAQ/Controller/Frontend/SetupController.php +++ b/phpmyfaq/src/phpMyFAQ/Controller/Frontend/SetupController.php @@ -38,19 +38,24 @@ class SetupController * @throws \Exception */ #[Route('/setup', name: 'public.setup.update')] - public function index(): Response + public function index(Request $request): Response { $system = new System(); $installer = new Installer($system); $checkBasicError = ''; - try { $installer->checkBasicStuff(); } catch (Exception $e) { $checkBasicError = $e->getMessage(); } + try { + $installer->checkInitialRewriteBasePath($request); + } catch (Exception $e) { + $checkBasicError = $e->getMessage(); + } + return $this->render( 'setup/index.twig', [ @@ -104,8 +109,9 @@ public function install(): Response /** * @throws TemplateException * @throws Exception + * @throws \Exception */ - #[Route('/setup/update', name: 'public.setup.update')] + #[Route('/update', name: 'public.setup.update')] public function update(Request $request): Response { $currentStep = Filter::filterVar($request->get('step'), FILTER_VALIDATE_INT); @@ -114,12 +120,20 @@ public function update(Request $request): Response $update = new Update(new System(), $configuration); + $checkBasicError = ''; + try { + $update->checkInitialRewriteBasePath($request); + } catch (Exception $e) { + $checkBasicError = $e->getMessage(); + } + return $this->render( 'setup/update.twig', [ 'currentStep' => $currentStep ?? 1, 'installedVersion' => $configuration->getVersion(), 'newVersion' => System::getVersion(), + 'checkBasicError' => $checkBasicError, 'currentYear' => date('Y'), 'documentationUrl' => System::getDocumentationUrl(), 'configTableNotAvailable' => $update->isConfigTableNotAvailable($configuration->getDb()), diff --git a/phpmyfaq/src/phpMyFAQ/Setup/Installer.php b/phpmyfaq/src/phpMyFAQ/Setup/Installer.php index 5f111d8269..b02594be41 100644 --- a/phpmyfaq/src/phpMyFAQ/Setup/Installer.php +++ b/phpmyfaq/src/phpMyFAQ/Setup/Installer.php @@ -41,6 +41,12 @@ use phpMyFAQ\Link; use phpMyFAQ\System; use phpMyFAQ\User; +use SplFileObject; +use Symfony\Component\HttpFoundation\Request; +use Tivie\HtaccessParser\Exception\SyntaxException; +use Tivie\HtaccessParser\Parser; + +use const Tivie\HtaccessParser\Token\TOKEN_DIRECTIVE; /** * Class Installer @@ -733,6 +739,34 @@ public function checkNoncriticalSettings(): array return $hints; } + /** + * @throws Exception + */ + public function checkInitialRewriteBasePath(Request $request): bool + { + $basePath = $request->getBasePath(); + $basePath = rtrim($basePath, 'setup'); + + $htaccessPath = PMF_ROOT_DIR . '/.htaccess'; + + $file = new SplFileObject($htaccessPath); + $parser = new Parser(); + try { + $htaccess = $parser->parse($file); + } catch (SyntaxException $e) { + throw new Exception('Syntax error in .htaccess file: ' . $e->getMessage()); + } catch (\Tivie\HtaccessParser\Exception\Exception $e) { + throw new Exception('Error parsing .htaccess file: ' . $e->getMessage()); + } + $rewriteBase = $htaccess->search('RewriteBase', TOKEN_DIRECTIVE); + + $rewriteBase->removeArgument($rewriteBase->getArguments()[0]); + $rewriteBase->setArguments((array)$basePath); + + $output = (string) $htaccess; + return file_put_contents($htaccessPath, $output); + } + /** * Starts the installation. * diff --git a/phpmyfaq/src/phpMyFAQ/Setup/Update.php b/phpmyfaq/src/phpMyFAQ/Setup/Update.php index 294b66ecfa..68357d4963 100644 --- a/phpmyfaq/src/phpMyFAQ/Setup/Update.php +++ b/phpmyfaq/src/phpMyFAQ/Setup/Update.php @@ -29,8 +29,14 @@ use phpMyFAQ\User; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; +use SplFileObject; +use Symfony\Component\HttpFoundation\Request; +use Tivie\HtaccessParser\Exception\SyntaxException; +use Tivie\HtaccessParser\Parser; use ZipArchive; +use const Tivie\HtaccessParser\Token\TOKEN_DIRECTIVE; + class Update extends Setup { private string $version; @@ -103,6 +109,38 @@ public function createConfigBackup(string $configDir): string return $this->configuration->getDefaultUrl() . 'content/core/config/' . $this->getBackupFilename(); } + + /** + * @throws Exception + */ + public function checkInitialRewriteBasePath(Request $request): bool + { + $basePath = $request->getBasePath(); + $basePath = rtrim($basePath, 'update'); + + $htaccessPath = PMF_ROOT_DIR . '/.htaccess'; + + $file = new SplFileObject($htaccessPath); + $parser = new Parser(); + + try { + $htaccess = $parser->parse($file); + } catch (SyntaxException $e) { + throw new Exception('Syntax error in .htaccess file: ' . $e->getMessage()); + } catch (\Tivie\HtaccessParser\Exception\Exception $e) { + throw new Exception('Error parsing .htaccess file: ' . $e->getMessage()); + } + + $rewriteBase = $htaccess->search('RewriteBase', TOKEN_DIRECTIVE); + + $rewriteBase->removeArgument($rewriteBase->getArguments()[0]); + $rewriteBase->setArguments((array)$basePath); + + $output = (string) $htaccess; + return file_put_contents($htaccessPath, $output); + } + + /** * @throws Exception * @throws \Exception